diff --git a/README.md b/README.md index 9471474..7fd4e88 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,113 @@ # Chytanka -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.0. +**Chytanka** is a versatile and user-friendly PWA for reading manga, comics, and other visual stories. Whether you prefer to read from popular online platforms, your own server, or local files, Chytanka is here to enhance your reading experience. + +## Features + +### 🖥️ **Read Episodes Online** + +Chytanka supports opening episodes from the following platforms: + +- [x] [Blankary](https://blankary.com) +- [x] [Comick](https://comick.io) +- [x] [Imgur](https://imgur.com) +- [x] [Mangadex](https://mangadex.org) +- [x] [Nhentai](https://nhentai.net) +- [x] [Pixiv](https://pixiv.net) +- [x] [Reddit](https://reddit.com) +- [x] [Telegra.ph](https://telegra.ph) +- [x] [Yande.re Pool](https://yande.re/pool) +- [x] [Zenko](https://zenko.online) + +### 🌐 **Custom JSON API** + +Chytanka can open episodes from any custom JSON API returning the following format: + +```json +{ +"title": "Title of the episode", +"nsfw": false, +"images": [ + { + "src": "full-link-to-image-1" + }, + { + "src": "full-link-to-image-2" + }, + { + "src": "full-link-to-image-n" + } +] +} +``` + +### 📚 **Create and Share Readlists** + +Compile a readlist using [Chytanka Readlist Creator](https://chytanka.ink/list): + +1. Paste supported links into the input field. +2. Edit titles (optional; automatic retrieval supported). +3. Generate and publish a JSON readlist on Rentry, Gist, or your server. +4. Use the generated link to start reading with your custom readlist. + +### 📂 **Open Local Files** + +Chytanka supports opening the following file formats from your device: + +- [x] ZIP/CBZ +- [x] PDF +- [x] MOBI +- [ ] DJVU +- [ ] RAR/CBR + +### 📖 **Three Reading Modes** + +1. **Vertical**: Perfect for webtoons. +2. **Horizontal (RTL)**: Best for manga. +3. **Horizontal (LTR)**: Ideal for comics. + +### 🌓 **Blue Light Filter** + +Read comfortably at night with Chytanka's built-in blue light filter. + +### 📱 **Responsive Viewing** + +- In horizontal mode with landscape orientation: view two pages side by side. +- In portrait orientation: view one page at a time. + +### 🖥️ **Fullscreen Mode** + +Immerse yourself in reading with a fullscreen option. + +### 🕒 **Viewing History** + +- [x] Tracks history of supported links. +- [ ] File history support is planned. + +### ⌨️ **Keyboard Shortcuts** + +#### On the Start Page: + +- `F1` — Open FAQ +- `F2` — Open Settings +- `Ctrl+H` — Open History +- `Ctrl+O` — Open File + +#### While Reading: + +- `A`, `D`, `ArrowLeft`, `ArrowRight` — Navigate pages in horizontal mode +- `W`, `S`, `ArrowUp`, `ArrowDown` — Navigate pages in vertical mode +- `Ctrl+O` — Open File +- `Ctrl+E` — Share (copy link or embed code) +- `F` — Toggle Fullscreen + +### 🔞 **NSFW Content Warning** + +If supported by the API, Chytanka warns users about NSFW content. + +### 🖇️ **Embed Chytanka on Your Website** + +Embed Chytanka using an iframe and interact with it via `postMessage`. Learn more in the [Embedding Guide](https://github.com/chytanka/chytanka.github.io/wiki/Embedding-Chytanka-on-Your-Website). ## Development server diff --git a/angular.json b/angular.json index eceb153..0a93052 100644 --- a/angular.json +++ b/angular.json @@ -42,6 +42,7 @@ "build": { "builder": "@angular-devkit/build-angular:application", "options": { + "allowedCommonJsDependencies": ["jszip"], "outputPath": "dist/chytanka", "index": "src/index.html", "browser": "src/main.ts", @@ -53,7 +54,8 @@ "assets": [ "src/favicon.ico", "src/assets", - "src/.well-known", + "src/robots.txt", + "src/sitemap.xml", "src/manifest.webmanifest", "src/manifest-uk.webmanifest", "src/CNAME" diff --git a/package-lock.json b/package-lock.json index 535966a..b0e1af0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "jszip": "^3.10.1", "ngx-highlightjs": "^12.0.0", "pdfjs-dist": "^4.6.82", + "readiverse": "^0.1.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.10" @@ -11538,6 +11539,30 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/readiverse": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/readiverse/-/readiverse-0.1.0.tgz", + "integrity": "sha512-POzuAZK9lGPWKrDvZbUpXkzS93BF/BOHAVvspWxRC5+7/iOd8Q3Aur2Skb+89PIhaWzY68YtKui+c7JmgHspMw==", + "license": "MIT", + "dependencies": { + "@types/node": "^22.7.5" + } + }, + "node_modules/readiverse/node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/readiverse/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/reflect-metadata": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", diff --git a/package.json b/package.json index 0de0b53..ef46e64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chytanka", - "version": "0.1.25", + "version": "0.14.28", "scripts": { "ng": "ng", "start": "ng serve", @@ -29,6 +29,7 @@ "jszip": "^3.10.1", "ngx-highlightjs": "^12.0.0", "pdfjs-dist": "^4.6.82", + "readiverse": "^0.1.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.10" diff --git a/scripts/generate-site-module.sh b/scripts/generate-site-module.sh new file mode 100755 index 0000000..051ef1e --- /dev/null +++ b/scripts/generate-site-module.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Default directory if not provided +DEFAULT_DIR="@site-modules" + +# Check if the module name is provided +if [ -z "$1" ]; then + echo "Usage: $0 [dir]" + exit 1 +fi + +MODULE_NAME=$1 +DIR=${2:-$DEFAULT_DIR} # Use second argument or default to @site-modules + +echo "Creating module $MODULE_NAME in directory $DIR..." + +# Generate the module with routing +ng g m "$DIR/$MODULE_NAME" --routing + +# Generate the shell component +ng g c "$DIR/$MODULE_NAME/$MODULE_NAME-shell" --no-standalone + +# Generate the service for data-access +ng g s "$DIR/$MODULE_NAME/data-access/$MODULE_NAME" + +echo "Module $MODULE_NAME successfully created in $DIR." \ No newline at end of file diff --git a/src/.well-known/atproto-did b/src/.well-known/atproto-did deleted file mode 100644 index 1bb4136..0000000 --- a/src/.well-known/atproto-did +++ /dev/null @@ -1 +0,0 @@ -did:plc:y7mx7g4jhmi3xeqxhvwxic4m \ No newline at end of file diff --git a/src/CNAME b/src/CNAME deleted file mode 100644 index 036ee5a..0000000 --- a/src/CNAME +++ /dev/null @@ -1 +0,0 @@ -chtnk.c \ No newline at end of file diff --git a/src/app/common/common-read/common-read.module.ts b/src/app/@site-modules/@common-read/common-read.module.ts similarity index 100% rename from src/app/common/common-read/common-read.module.ts rename to src/app/@site-modules/@common-read/common-read.module.ts diff --git a/src/app/common/common-read/index.ts b/src/app/@site-modules/@common-read/index.ts similarity index 100% rename from src/app/common/common-read/index.ts rename to src/app/@site-modules/@common-read/index.ts diff --git a/src/app/common/common-read/ui/common-read/common-read.component.html b/src/app/@site-modules/@common-read/ui/common-read/common-read.component.html similarity index 100% rename from src/app/common/common-read/ui/common-read/common-read.component.html rename to src/app/@site-modules/@common-read/ui/common-read/common-read.component.html diff --git a/src/app/common/common-read/ui/common-read/common-read.component.scss b/src/app/@site-modules/@common-read/ui/common-read/common-read.component.scss similarity index 100% rename from src/app/common/common-read/ui/common-read/common-read.component.scss rename to src/app/@site-modules/@common-read/ui/common-read/common-read.component.scss diff --git a/src/app/common/common-read/ui/common-read/common-read.component.ts b/src/app/@site-modules/@common-read/ui/common-read/common-read.component.ts similarity index 100% rename from src/app/common/common-read/ui/common-read/common-read.component.ts rename to src/app/@site-modules/@common-read/ui/common-read/common-read.component.ts diff --git a/src/app/common/common-read/ui/index.ts b/src/app/@site-modules/@common-read/ui/index.ts similarity index 100% rename from src/app/common/common-read/ui/index.ts rename to src/app/@site-modules/@common-read/ui/index.ts diff --git a/src/app/common/common-read/utils/composition.ts b/src/app/@site-modules/@common-read/utils/composition.ts similarity index 100% rename from src/app/common/common-read/utils/composition.ts rename to src/app/@site-modules/@common-read/utils/composition.ts diff --git a/src/app/common/common-read/utils/index.ts b/src/app/@site-modules/@common-read/utils/index.ts similarity index 100% rename from src/app/common/common-read/utils/index.ts rename to src/app/@site-modules/@common-read/utils/index.ts diff --git a/src/app/common/common-read/utils/read-base-component.ts b/src/app/@site-modules/@common-read/utils/read-base-component.ts similarity index 81% rename from src/app/common/common-read/utils/read-base-component.ts rename to src/app/@site-modules/@common-read/utils/read-base-component.ts index 4eeb834..30c2225 100644 --- a/src/app/common/common-read/utils/read-base-component.ts +++ b/src/app/@site-modules/@common-read/utils/read-base-component.ts @@ -7,6 +7,7 @@ import { LangService } from "../../../shared/data-access/lang.service"; import { HistoryService } from "../../../history/data-access/history.service"; import { ViewerService } from "../../../shared/data-access"; import { PlaylistItem, PlaylistService, isPlaylist } from "../../../playlist/data-access/playlist.service"; +import { MetaTagsService } from "../../../shared/data-access/meta-tags.service"; export abstract class ReadBaseComponent { protected refresh$: BehaviorSubject = new BehaviorSubject(null); @@ -38,7 +39,7 @@ export abstract class ReadBaseComponent { }) } - private title: Title = inject(Title) + meta = inject(MetaTagsService) protected route: ActivatedRoute = inject(ActivatedRoute) public lang: LangService = inject(LangService) @@ -82,11 +83,29 @@ export abstract class ReadBaseComponent { }) } - protected tapSetTitle(): MonoTypeOperatorFunction { - return tap(async (episode: CompositionEpisode) => { - if (episode) { - this.title.setTitle(`${episode.title} | Chytanka`); - } + // protected tapSetTitle(): MonoTypeOperatorFunction { + // return tap(async (episode: CompositionEpisode) => { + // if (episode) { + // this.title.setTitle(`${episode.title} | Chytanka`); + // } + // }) + // } + + protected tapSetMetaTags(copyrights = ''): MonoTypeOperatorFunction { + return tap((v) => { + + const t = v?.title; + this.meta.setOg(); + this.meta.setTwiter() + this.meta.setTitle(`Читати ${t} онлайн в Читанці`) + this.meta.setDesc(`Читати ${t} онлайн в Читанці`) + this.meta.setImage(v.images[0].src, t, '', copyrights) + // this.meta.setOgUrl(`https://chtnk.online/${v.id}/${MangadexHelper.getAlias(v.attributes)}`) + + // if (isNSFW(v.attributes)) { + // this.meta.setAdult() + // } + }) } @@ -113,14 +132,14 @@ export abstract class ReadBaseComponent { return tap(async (episode: CompositionEpisode) => { if (episode) { - + this.currentPlItem.set({ id: post_id, site: site }) this.cdr.detectChanges() } - + }) } } \ No newline at end of file diff --git a/src/app/@site-modules/blankary/blankary-routing.module.ts b/src/app/@site-modules/blankary/blankary-routing.module.ts new file mode 100644 index 0000000..5511c82 --- /dev/null +++ b/src/app/@site-modules/blankary/blankary-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { BlankaryShellComponent } from './blankary-shell/blankary-shell.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/', pathMatch: 'full' }, + { + path: ':id', + component: BlankaryShellComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class BlankaryRoutingModule { } diff --git a/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.html b/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.html new file mode 100644 index 0000000..0dc6e81 --- /dev/null +++ b/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.html @@ -0,0 +1,8 @@ + + +

{{lang.ph().imagesVia}}Blankary + API. + {{lang.ph().thanks}}
{{lang.ph().detalisCopy}}

+ +
\ No newline at end of file diff --git a/src/app/comick/comick-shell/comick-shell.component.scss b/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.scss similarity index 100% rename from src/app/comick/comick-shell/comick-shell.component.scss rename to src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.scss diff --git a/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.ts b/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.ts new file mode 100644 index 0000000..08031a4 --- /dev/null +++ b/src/app/@site-modules/blankary/blankary-shell/blankary-shell.component.ts @@ -0,0 +1,46 @@ +import { Component, inject, OnDestroy } from '@angular/core'; +import { switchMap, of, MonoTypeOperatorFunction, tap } from 'rxjs'; +import { BLANKARY_PATH } from '../../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; +import { BlankaryService } from '../data-access/blankary.service'; +import { MetaTagsService } from '../../../shared/data-access/meta-tags.service'; + +@Component({ + selector: 'app-blankary-shell', + templateUrl: './blankary-shell.component.html', + styleUrl: './blankary-shell.component.scss' +}) +export class BlankaryShellComponent extends ReadBaseComponent implements OnDestroy { + blankary = inject(BlankaryService) + + + override episode$ = this.combineParamMapAndRefresh() + .pipe(this.tapStartLoading(), + switchMap(([params]) => { + const pathParam = params?.get('id'); + + if (!pathParam) return of(null); + + const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; + + return (this.blankary.getComposition(path)).pipe( + this.catchError(), + this.tapSetMetaTags(), + this.tapSaveToHistory(BLANKARY_PATH, path), + this.tapSaveToCurrentPlaylistItem(BLANKARY_PATH, path), + this.finalizeLoading()); + }) + ); + + constructor() { + super() + } + + ngOnDestroy(): void { + this.plObserv?.unsubscribe(); + } + + + +} diff --git a/src/app/@site-modules/blankary/blankary.module.ts b/src/app/@site-modules/blankary/blankary.module.ts new file mode 100644 index 0000000..425f6e3 --- /dev/null +++ b/src/app/@site-modules/blankary/blankary.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { BlankaryRoutingModule } from './blankary-routing.module'; +import { BlankaryShellComponent } from './blankary-shell/blankary-shell.component'; +import { CommonReadModule } from '../@common-read'; + + +@NgModule({ + declarations: [ + BlankaryShellComponent + ], + imports: [ + CommonModule, + BlankaryRoutingModule, + CommonReadModule + ] +}) +export class BlankaryModule { } diff --git a/src/app/@site-modules/blankary/data-access/blankary.service.ts b/src/app/@site-modules/blankary/data-access/blankary.service.ts new file mode 100644 index 0000000..24e65db --- /dev/null +++ b/src/app/@site-modules/blankary/data-access/blankary.service.ts @@ -0,0 +1,34 @@ +import { HttpClient } from '@angular/common/http'; +import { inject, Injectable } from '@angular/core'; +import { map, Observable } from 'rxjs'; +import { CompositionEpisode } from '../../@common-read'; +import { environment } from '../../../../environments/environment'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; + +@Injectable({ + providedIn: 'root' +}) +export class BlankaryService { + http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) + + getComposition(id: string): Observable { + return this.http.get(this.proxy.proxyUrl(environment.blankaryoHost + id)) + .pipe(map((data) => { return this.map(data) })) + } + + map(data: any): CompositionEpisode { + const mappedResponse = { + title: data.title, + + images: JSON.parse(data.images).map((img: string) => { + return { + src: this.proxy.proxyUrl(`https://blankary.com/image/${img}`) + }; + }) + + }; + + return mappedResponse; + } +} diff --git a/src/app/comick/comick-routing.module.ts b/src/app/@site-modules/comick/comick-routing.module.ts similarity index 100% rename from src/app/comick/comick-routing.module.ts rename to src/app/@site-modules/comick/comick-routing.module.ts diff --git a/src/app/comick/comick-shell/comick-shell.component.html b/src/app/@site-modules/comick/comick-shell/comick-shell.component.html similarity index 100% rename from src/app/comick/comick-shell/comick-shell.component.html rename to src/app/@site-modules/comick/comick-shell/comick-shell.component.html diff --git a/src/app/nhentai/nhentai-shell/nhentai-shell.component.scss b/src/app/@site-modules/comick/comick-shell/comick-shell.component.scss similarity index 100% rename from src/app/nhentai/nhentai-shell/nhentai-shell.component.scss rename to src/app/@site-modules/comick/comick-shell/comick-shell.component.scss diff --git a/src/app/comick/comick-shell/comick-shell.component.ts b/src/app/@site-modules/comick/comick-shell/comick-shell.component.ts similarity index 84% rename from src/app/comick/comick-shell/comick-shell.component.ts rename to src/app/@site-modules/comick/comick-shell/comick-shell.component.ts index f337ac5..ba1c0ec 100644 --- a/src/app/comick/comick-shell/comick-shell.component.ts +++ b/src/app/@site-modules/comick/comick-shell/comick-shell.component.ts @@ -1,9 +1,9 @@ import { Component, inject, OnDestroy } from '@angular/core'; import { ComickService } from '../data-access/comick.service'; import { switchMap, of } from 'rxjs'; -import { ReadBaseComponent } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; -import { COMICK_PATH } from '../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; +import { COMICK_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-comick-shell', @@ -22,7 +22,7 @@ export class ComickShellComponent extends ReadBaseComponent implements OnDestroy const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.comick.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.comick.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(), this.tapSaveToHistory(COMICK_PATH, path), this.tapSaveToCurrentPlaylistItem(COMICK_PATH, path), this.finalizeLoading()); diff --git a/src/app/comick/comick.module.ts b/src/app/@site-modules/comick/comick.module.ts similarity index 87% rename from src/app/comick/comick.module.ts rename to src/app/@site-modules/comick/comick.module.ts index 6b0d441..37aeb07 100644 --- a/src/app/comick/comick.module.ts +++ b/src/app/@site-modules/comick/comick.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { ComickRoutingModule } from './comick-routing.module'; import { ComickShellComponent } from './comick-shell/comick-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/comick/data-access/comick.service.ts b/src/app/@site-modules/comick/data-access/comick.service.ts similarity index 75% rename from src/app/comick/data-access/comick.service.ts rename to src/app/@site-modules/comick/data-access/comick.service.ts index d80f249..ddc3ea6 100644 --- a/src/app/comick/data-access/comick.service.ts +++ b/src/app/@site-modules/comick/data-access/comick.service.ts @@ -1,18 +1,19 @@ import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CompositionEpisode } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { environment } from '../../../../environments/environment'; +import { CompositionEpisode } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class ComickService { http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getComposition(id: string): Observable { - // environment.proxy + Base64.toBase64 + // this.proxy.proxyUrl() return this.http.get((environment.comickHost + id)) .pipe(map((data) => { return this.map(data) })) } @@ -31,7 +32,7 @@ export class ComickService { })).filter((i: any) => i.src) // .map((img: any) => { // return { - // src: environment.proxy + Base64.toBase64(`${img.src}`) + // src: this.proxy.proxyUrl(`${img.src}`) // } // }) diff --git a/src/app/imgur/data-access/imgur.service.ts b/src/app/@site-modules/imgur/data-access/imgur.service.ts similarity index 95% rename from src/app/imgur/data-access/imgur.service.ts rename to src/app/@site-modules/imgur/data-access/imgur.service.ts index fdf0610..6feab8e 100644 --- a/src/app/imgur/data-access/imgur.service.ts +++ b/src/app/@site-modules/imgur/data-access/imgur.service.ts @@ -1,8 +1,8 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; import { Observable, map } from 'rxjs'; -import { CompositionEpisode, CompositionImage } from '../../common/common-read'; +import { CompositionEpisode, CompositionImage } from '../../@common-read'; interface ImgurRespCompImage { link: string; width: number; diff --git a/src/app/imgur/imgur-routing.module.ts b/src/app/@site-modules/imgur/imgur-routing.module.ts similarity index 100% rename from src/app/imgur/imgur-routing.module.ts rename to src/app/@site-modules/imgur/imgur-routing.module.ts diff --git a/src/app/imgur/imgur-shell/imgur-shell.component.ts b/src/app/@site-modules/imgur/imgur-shell/imgur-shell.component.ts similarity index 89% rename from src/app/imgur/imgur-shell/imgur-shell.component.ts rename to src/app/@site-modules/imgur/imgur-shell/imgur-shell.component.ts index 0a92cfc..0deb53e 100644 --- a/src/app/imgur/imgur-shell/imgur-shell.component.ts +++ b/src/app/@site-modules/imgur/imgur-shell/imgur-shell.component.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core'; import { ImgurService } from '../data-access/imgur.service'; -import { Base64 } from '../../shared/utils'; +import { Base64 } from '../../../shared/utils'; import { of, switchMap } from 'rxjs'; -import { ReadBaseComponent } from '../../common/common-read'; -import { IMGUR_PATH } from '../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { IMGUR_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-imgur-shell', @@ -30,7 +30,7 @@ export class ImgurShellComponent extends ReadBaseComponent { const id = (Base64.isBase64(idParam)) ? Base64.fromBase64(idParam) : idParam; const id64 = Base64.toBase64(id); - return (this.imgur.getComposition(id)).pipe(this.catchError(), this.tapSetTitle(), + return (this.imgur.getComposition(id)).pipe(this.catchError(), this.tapSetMetaTags(), this.tapSaveToHistory(IMGUR_PATH, id64), this.tapSaveToCurrentPlaylistItem(IMGUR_PATH, id), diff --git a/src/app/imgur/imgur.module.ts b/src/app/@site-modules/imgur/imgur.module.ts similarity index 87% rename from src/app/imgur/imgur.module.ts rename to src/app/@site-modules/imgur/imgur.module.ts index a8b88aa..d3e9df3 100644 --- a/src/app/imgur/imgur.module.ts +++ b/src/app/@site-modules/imgur/imgur.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { ImgurRoutingModule } from './imgur-routing.module'; import { ImgurShellComponent } from './imgur-shell/imgur-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/@site-modules/index.ts b/src/app/@site-modules/index.ts new file mode 100644 index 0000000..b5393d5 --- /dev/null +++ b/src/app/@site-modules/index.ts @@ -0,0 +1,12 @@ +export * from './blankary/blankary.module' +export * from './comick/comick.module' +export * from './imgur/imgur.module' +export * from './mangadex/mangadex.module' +export * from './nhentai/nhentai.module' +export * from './pixiv/pixiv.module' +export * from './reddit/reddit.module' +export * from './telegraph/telegraph.module' +export * from './yandere/yandere.module' +export * from './zenko/zenko.module' +// link to json data +export * from './read/read.module' \ No newline at end of file diff --git a/src/app/mangadex/data-access/mangadex.service.ts b/src/app/@site-modules/mangadex/data-access/mangadex.service.ts similarity index 78% rename from src/app/mangadex/data-access/mangadex.service.ts rename to src/app/@site-modules/mangadex/data-access/mangadex.service.ts index eeb6b68..2801e98 100644 --- a/src/app/mangadex/data-access/mangadex.service.ts +++ b/src/app/@site-modules/mangadex/data-access/mangadex.service.ts @@ -1,8 +1,9 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { environment } from '../../../environments/environment'; +import { inject, Injectable } from '@angular/core'; +import { environment } from '../../../../environments/environment'; import { Observable, catchError, map, throwError } from 'rxjs'; -import { CompositionEpisode, CompositionImage } from '../../common/common-read'; +import { CompositionEpisode, CompositionImage } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; interface MdChapterImages { hash: string; @@ -62,15 +63,15 @@ interface MdMangaResp { providedIn: 'root' }) export class MangadexService { - - constructor(private http: HttpClient) { } + http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getChapterImages(id: string): Observable { - return this.http.get(environment.mangadexHost + id) + return this.http.get(this.proxy.proxyUrl(environment.mangadexHost + id)) .pipe( map((data: MdChapterImagesResp) => data.chapter.dataSaver.map((item: string) => { return { - src: `${environment.proxy}${data.baseUrl}/data-saver/${data.chapter.hash}/${item}` + src: this.proxy.proxyUrl(`${data.baseUrl}/data-saver/${data.chapter.hash}/${item}`) // src: `${data.baseUrl}/data/${data.chapter.hash}/${item}` } }) @@ -80,7 +81,7 @@ export class MangadexService { } getChapter(id: string): Observable { - return this.http.get(environment.mangadexChapter + id) + return this.http.get(this.proxy.proxyUrl(environment.mangadexChapter + id)) .pipe( map((data: MdChapterResp) => { return { @@ -98,7 +99,7 @@ export class MangadexService { getManga(id: string): Observable<{ nsfw: boolean }> { - return this.http.get(environment.mangadexManga + id).pipe(this.nsfwMap()) + return this.http.get(this.proxy.proxyUrl(environment.mangadexManga + id)).pipe(this.nsfwMap()) } nsfwMap() { diff --git a/src/app/mangadex/mangadex-routing.module.ts b/src/app/@site-modules/mangadex/mangadex-routing.module.ts similarity index 100% rename from src/app/mangadex/mangadex-routing.module.ts rename to src/app/@site-modules/mangadex/mangadex-routing.module.ts diff --git a/src/app/mangadex/mangadex-shell/mangadex-shell.component.ts b/src/app/@site-modules/mangadex/mangadex-shell/mangadex-shell.component.ts similarity index 91% rename from src/app/mangadex/mangadex-shell/mangadex-shell.component.ts rename to src/app/@site-modules/mangadex/mangadex-shell/mangadex-shell.component.ts index d97327e..2e24d74 100644 --- a/src/app/mangadex/mangadex-shell/mangadex-shell.component.ts +++ b/src/app/@site-modules/mangadex/mangadex-shell/mangadex-shell.component.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core'; import { forkJoin, map, of, switchMap } from 'rxjs'; import { MangadexService } from '../data-access/mangadex.service'; -import { Base64 } from '../../shared/utils'; -import { ReadBaseComponent } from '../../common/common-read'; -import { MANGADEX_PATH } from '../../app-routing.module'; +import { Base64 } from '../../../shared/utils'; +import { ReadBaseComponent } from '../../@common-read'; +import { MANGADEX_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-mangadex-shell', @@ -50,7 +50,7 @@ export class MangadexShellComponent extends ReadBaseComponent { ); }), this.catchError(), - this.tapSetTitle(), + this.tapSetMetaTags(MANGADEX_PATH), this.tapSaveToHistory(MANGADEX_PATH, id64), this.tapSaveToCurrentPlaylistItem(MANGADEX_PATH, id), diff --git a/src/app/mangadex/mangadex.module.ts b/src/app/@site-modules/mangadex/mangadex.module.ts similarity index 88% rename from src/app/mangadex/mangadex.module.ts rename to src/app/@site-modules/mangadex/mangadex.module.ts index 4151ab1..3774c69 100644 --- a/src/app/mangadex/mangadex.module.ts +++ b/src/app/@site-modules/mangadex/mangadex.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { MangadexRoutingModule } from './mangadex-routing.module'; import { MangadexShellComponent } from './mangadex-shell/mangadex-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/nhentai/data-access/nhentai.service.ts b/src/app/@site-modules/nhentai/data-access/nhentai.service.ts similarity index 69% rename from src/app/nhentai/data-access/nhentai.service.ts rename to src/app/@site-modules/nhentai/data-access/nhentai.service.ts index f26ab8b..4bcb640 100644 --- a/src/app/nhentai/data-access/nhentai.service.ts +++ b/src/app/@site-modules/nhentai/data-access/nhentai.service.ts @@ -1,22 +1,23 @@ import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CompositionEpisode } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { environment } from '../../../../environments/environment'; +import { CompositionEpisode } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class NhentaiService { http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getComposition(id: string): Observable { - return this.http.get(environment.proxy + Base64.toBase64(environment.nhentaiHost + id)) + return this.http.get(this.proxy.proxyUrl(environment.nhentaiHost + id)) .pipe(map((data) => { return this.map(data) })) } - imageType = new Map().set('p', 'png').set('j', 'jpg').set('g', 'gif') + imageType = new Map().set('p', 'png').set('j', 'jpg').set('g', 'gif').set('w', 'webp') map(data: any): CompositionEpisode { const mediaId = data.media_id; @@ -31,7 +32,7 @@ export class NhentaiService { }; })).filter((i: any) => i.src) .map((img: any) => { - return { src: environment.proxy + Base64.toBase64(`${img.src}`) } + return { src: this.proxy.proxyUrl(`${img.src}`) } }) }; diff --git a/src/app/nhentai/nhentai-routing.module.ts b/src/app/@site-modules/nhentai/nhentai-routing.module.ts similarity index 100% rename from src/app/nhentai/nhentai-routing.module.ts rename to src/app/@site-modules/nhentai/nhentai-routing.module.ts diff --git a/src/app/nhentai/nhentai-shell/nhentai-shell.component.html b/src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.html similarity index 100% rename from src/app/nhentai/nhentai-shell/nhentai-shell.component.html rename to src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.html diff --git a/src/app/pixiv/pixiv-shell/pixiv-shell.component.scss b/src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.scss similarity index 100% rename from src/app/pixiv/pixiv-shell/pixiv-shell.component.scss rename to src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.scss diff --git a/src/app/nhentai/nhentai-shell/nhentai-shell.component.ts b/src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.ts similarity index 84% rename from src/app/nhentai/nhentai-shell/nhentai-shell.component.ts rename to src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.ts index f7c29b3..df787d4 100644 --- a/src/app/nhentai/nhentai-shell/nhentai-shell.component.ts +++ b/src/app/@site-modules/nhentai/nhentai-shell/nhentai-shell.component.ts @@ -1,9 +1,9 @@ import { Component, inject, OnDestroy } from '@angular/core'; import { NhentaiService } from '../data-access/nhentai.service'; import { switchMap, of } from 'rxjs'; -import { NHENTAI_PATH } from '../../app-routing.module'; -import { Base64 } from '../../shared/utils'; -import { ReadBaseComponent } from '../../common/common-read'; +import { NHENTAI_PATH } from '../../../app-routing.module'; +import { Base64 } from '../../../shared/utils'; +import { ReadBaseComponent } from '../../@common-read'; @Component({ selector: 'app-nhentai-shell', @@ -22,7 +22,7 @@ export class NhentaiShellComponent extends ReadBaseComponent implements OnDestro const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.nhentai.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.nhentai.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(), this.tapSaveToHistory(NHENTAI_PATH, path), this.tapSaveToCurrentPlaylistItem(NHENTAI_PATH, path), this.finalizeLoading()); diff --git a/src/app/nhentai/nhentai.module.ts b/src/app/@site-modules/nhentai/nhentai.module.ts similarity index 87% rename from src/app/nhentai/nhentai.module.ts rename to src/app/@site-modules/nhentai/nhentai.module.ts index d4c7d15..cf903c7 100644 --- a/src/app/nhentai/nhentai.module.ts +++ b/src/app/@site-modules/nhentai/nhentai.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { NhentaiRoutingModule } from './nhentai-routing.module'; import { NhentaiShellComponent } from './nhentai-shell/nhentai-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/pixiv/data-access/pixiv.service.ts b/src/app/@site-modules/pixiv/data-access/pixiv.service.ts similarity index 78% rename from src/app/pixiv/data-access/pixiv.service.ts rename to src/app/@site-modules/pixiv/data-access/pixiv.service.ts index b91ac65..ac50ea2 100644 --- a/src/app/pixiv/data-access/pixiv.service.ts +++ b/src/app/@site-modules/pixiv/data-access/pixiv.service.ts @@ -1,18 +1,19 @@ import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CompositionEpisode, CompositionPublisher } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { environment } from '../../../../environments/environment'; +import { CompositionEpisode, CompositionPublisher } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class PixivService { http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getComposition(id: string): Observable { - return this.http.get(environment.proxy + Base64.toBase64(environment.pixivHost + id)) + return this.http.get(this.proxy.proxyUrl(environment.pixivHost + id)) .pipe(map((data) => { return this.map(data.body) })) } @@ -25,7 +26,7 @@ export class PixivService { id: data.author_details.user_id as string, site: `https://pixiv.net/en/users/` + data.author_details.user_id as string, name: data.author_details.user_name as string, - avatar: environment.proxy + Base64.toBase64(data.author_details.profile_img.main) + '&ref=https://www.pixiv.net' as string, + avatar: this.proxy.proxyUrl(data.author_details.profile_img.main) + '&ref=https://www.pixiv.net' as string, description: '', links: [] } as unknown as CompositionPublisher, @@ -46,7 +47,7 @@ export class PixivService { .filter((i: any) => i.src).map((img: any) => { return { - src: environment.proxy + Base64.toBase64(img.src) + '&ref=https://www.pixiv.net', + src: this.proxy.proxyUrl(img.src) + '&ref=https://www.pixiv.net', width: img.width, height: img.height } diff --git a/src/app/pixiv/pixiv-routing.module.ts b/src/app/@site-modules/pixiv/pixiv-routing.module.ts similarity index 100% rename from src/app/pixiv/pixiv-routing.module.ts rename to src/app/@site-modules/pixiv/pixiv-routing.module.ts diff --git a/src/app/pixiv/pixiv-shell/pixiv-shell.component.html b/src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.html similarity index 100% rename from src/app/pixiv/pixiv-shell/pixiv-shell.component.html rename to src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.html diff --git a/src/app/yandere/yandere-shell/yandere-shell.component.scss b/src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.scss similarity index 100% rename from src/app/yandere/yandere-shell/yandere-shell.component.scss rename to src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.scss diff --git a/src/app/pixiv/pixiv-shell/pixiv-shell.component.ts b/src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.ts similarity index 84% rename from src/app/pixiv/pixiv-shell/pixiv-shell.component.ts rename to src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.ts index 05d6ceb..16707ca 100644 --- a/src/app/pixiv/pixiv-shell/pixiv-shell.component.ts +++ b/src/app/@site-modules/pixiv/pixiv-shell/pixiv-shell.component.ts @@ -1,9 +1,9 @@ import { Component, inject, OnDestroy } from '@angular/core'; import { PixivService } from '../data-access/pixiv.service'; -import { PIXIV_PATH } from '../../app-routing.module'; +import { PIXIV_PATH } from '../../../app-routing.module'; import { switchMap, of } from 'rxjs'; -import { ReadBaseComponent } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { ReadBaseComponent } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; @Component({ selector: 'app-pixiv-shell', @@ -22,7 +22,7 @@ export class PixivShellComponent extends ReadBaseComponent implements OnDestroy const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.pixiv.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.pixiv.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(), this.tapSaveToHistory(PIXIV_PATH, path), this.tapSaveToCurrentPlaylistItem(PIXIV_PATH, path), this.finalizeLoading()); diff --git a/src/app/pixiv/pixiv.module.ts b/src/app/@site-modules/pixiv/pixiv.module.ts similarity index 87% rename from src/app/pixiv/pixiv.module.ts rename to src/app/@site-modules/pixiv/pixiv.module.ts index bee58bd..5e3f4a9 100644 --- a/src/app/pixiv/pixiv.module.ts +++ b/src/app/@site-modules/pixiv/pixiv.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PixivRoutingModule } from './pixiv-routing.module'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; import { PixivShellComponent } from './pixiv-shell/pixiv-shell.component'; diff --git a/src/app/read/data-access/read.service.ts b/src/app/@site-modules/read/data-access/read.service.ts similarity index 96% rename from src/app/read/data-access/read.service.ts rename to src/app/@site-modules/read/data-access/read.service.ts index 0d0af5d..dbf434d 100644 --- a/src/app/read/data-access/read.service.ts +++ b/src/app/@site-modules/read/data-access/read.service.ts @@ -1,7 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable, catchError, tap, throwError } from 'rxjs'; -import { CompositionEpisode, isCompositionEpisode } from '../../common/common-read'; +import { CompositionEpisode, isCompositionEpisode } from '../../@common-read'; @Injectable({ providedIn: 'root' diff --git a/src/app/read/read-routing.module.ts b/src/app/@site-modules/read/read-routing.module.ts similarity index 100% rename from src/app/read/read-routing.module.ts rename to src/app/@site-modules/read/read-routing.module.ts diff --git a/src/app/read/read-shell/read-shell.component.ts b/src/app/@site-modules/read/read-shell/read-shell.component.ts similarity index 89% rename from src/app/read/read-shell/read-shell.component.ts rename to src/app/@site-modules/read/read-shell/read-shell.component.ts index edfb163..147ed4f 100644 --- a/src/app/read/read-shell/read-shell.component.ts +++ b/src/app/@site-modules/read/read-shell/read-shell.component.ts @@ -1,9 +1,9 @@ import { Component, signal } from '@angular/core'; import { of, switchMap } from 'rxjs'; import { ReadService } from '../data-access/read.service'; -import { Base64 } from '../../shared/utils'; -import { ReadBaseComponent } from '../../common/common-read'; -import { READ_PATH } from '../../app-routing.module'; +import { Base64 } from '../../../shared/utils'; +import { ReadBaseComponent } from '../../@common-read'; +import { READ_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-read-shell', @@ -32,7 +32,7 @@ export class ReadShellComponent extends ReadBaseComponent { return this.read.getComposition(url).pipe( this.catchError(), - this.tapSetTitle(), + this.tapSetMetaTags(), this.tapSaveToHistory(READ_PATH, id64), this.tapSaveToCurrentPlaylistItem(READ_PATH, url), diff --git a/src/app/read/read.module.ts b/src/app/@site-modules/read/read.module.ts similarity index 87% rename from src/app/read/read.module.ts rename to src/app/@site-modules/read/read.module.ts index 6cd48d1..8a7c4db 100644 --- a/src/app/read/read.module.ts +++ b/src/app/@site-modules/read/read.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReadShellComponent } from './read-shell/read-shell.component'; import { ReadRoutingModule } from './read-routing.module'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; diff --git a/src/app/reddit/data-access/reddit.service.ts b/src/app/@site-modules/reddit/data-access/reddit.service.ts similarity index 75% rename from src/app/reddit/data-access/reddit.service.ts rename to src/app/@site-modules/reddit/data-access/reddit.service.ts index 31a1dba..ab44171 100644 --- a/src/app/reddit/data-access/reddit.service.ts +++ b/src/app/@site-modules/reddit/data-access/reddit.service.ts @@ -1,14 +1,16 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CompositionEpisode } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { environment } from '../../../../environments/environment'; +import { CompositionEpisode } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; +import { Base64 } from '../../../shared/utils'; @Injectable({ providedIn: 'root' }) export class RedditService { + proxy: ProxyService = inject(ProxyService) constructor(private http: HttpClient) { } @@ -32,7 +34,7 @@ export class RedditService { const ext = (media_metadata[i.media_id]?.m).replace('image/', ''); const imgSrc = `https://i.redd.it/${i.media_id}.${ext ?? 'jpg'}` return { - src: environment.proxy + Base64.toBase64(imgSrc), + src: this.proxy.proxyUrl(imgSrc), height: (media_metadata[i.media_id]?.s).y, width: (media_metadata[i.media_id]?.s).x, } diff --git a/src/app/reddit/reddit-routing.module.ts b/src/app/@site-modules/reddit/reddit-routing.module.ts similarity index 100% rename from src/app/reddit/reddit-routing.module.ts rename to src/app/@site-modules/reddit/reddit-routing.module.ts diff --git a/src/app/reddit/reddit-shell/reddit-shell.component.ts b/src/app/@site-modules/reddit/reddit-shell/reddit-shell.component.ts similarity index 86% rename from src/app/reddit/reddit-shell/reddit-shell.component.ts rename to src/app/@site-modules/reddit/reddit-shell/reddit-shell.component.ts index fcf196b..b1d2716 100644 --- a/src/app/reddit/reddit-shell/reddit-shell.component.ts +++ b/src/app/@site-modules/reddit/reddit-shell/reddit-shell.component.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core'; -import { Base64 } from '../../shared/utils'; +import { Base64 } from '../../../shared/utils'; import { of, switchMap } from 'rxjs'; import { RedditService } from '../data-access/reddit.service'; -import { ReadBaseComponent } from '../../common/common-read'; -import { REDDIT_PATH } from '../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { REDDIT_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-reddit-shell', @@ -29,7 +29,7 @@ export class RedditShellComponent extends ReadBaseComponent { return (this.reddit.getComposition(id)).pipe( this.catchError(), - this.tapSetTitle(), + this.tapSetMetaTags(REDDIT_PATH), this.tapSaveToHistory(REDDIT_PATH, id64), this.tapSaveToCurrentPlaylistItem(REDDIT_PATH, id), diff --git a/src/app/reddit/reddit.module.ts b/src/app/@site-modules/reddit/reddit.module.ts similarity index 87% rename from src/app/reddit/reddit.module.ts rename to src/app/@site-modules/reddit/reddit.module.ts index 82d4b80..0478cf6 100644 --- a/src/app/reddit/reddit.module.ts +++ b/src/app/@site-modules/reddit/reddit.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { RedditRoutingModule } from './reddit-routing.module'; import { RedditShellComponent } from './reddit-shell/reddit-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/telegraph/data-access/telegraph.service.ts b/src/app/@site-modules/telegraph/data-access/telegraph.service.ts similarity index 71% rename from src/app/telegraph/data-access/telegraph.service.ts rename to src/app/@site-modules/telegraph/data-access/telegraph.service.ts index 130d3c3..d554555 100644 --- a/src/app/telegraph/data-access/telegraph.service.ts +++ b/src/app/@site-modules/telegraph/data-access/telegraph.service.ts @@ -1,14 +1,15 @@ import { HttpClient, HttpParams } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { CompositionEpisode } from '../../common/common-read'; -import { environment } from '../../../environments/environment'; -import { Base64 } from '../../shared/utils'; +import { CompositionEpisode } from '../../@common-read'; +import { environment } from '../../../../environments/environment'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class TelegraphService { + proxy: ProxyService = inject(ProxyService) constructor(private http: HttpClient) { } @@ -27,7 +28,7 @@ export class TelegraphService { src: item.children.find((child: any) => child.tag === "img")?.attrs.src }; })).filter((i: any) => i.src).map((img: any)=> {return {src: - environment.proxy + Base64.toBase64('https://telegra.ph'+ img.src) + this.proxy.proxyUrl('https://telegra.ph'+ img.src) }}) }; diff --git a/src/app/telegraph/telegraph-routing.module.ts b/src/app/@site-modules/telegraph/telegraph-routing.module.ts similarity index 100% rename from src/app/telegraph/telegraph-routing.module.ts rename to src/app/@site-modules/telegraph/telegraph-routing.module.ts diff --git a/src/app/telegraph/telegraph-shell/telegraph-shell.component.ts b/src/app/@site-modules/telegraph/telegraph-shell/telegraph-shell.component.ts similarity index 87% rename from src/app/telegraph/telegraph-shell/telegraph-shell.component.ts rename to src/app/@site-modules/telegraph/telegraph-shell/telegraph-shell.component.ts index fedf3b2..8e8a02e 100644 --- a/src/app/telegraph/telegraph-shell/telegraph-shell.component.ts +++ b/src/app/@site-modules/telegraph/telegraph-shell/telegraph-shell.component.ts @@ -1,9 +1,9 @@ import { Component, OnDestroy } from '@angular/core'; -import { Base64 } from '../../shared/utils'; +import { Base64 } from '../../../shared/utils'; import { of, switchMap } from 'rxjs'; import { TelegraphService } from '../data-access/telegraph.service'; -import { ReadBaseComponent } from '../../common/common-read'; -import { TELEGRAPH_PATH } from '../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { TELEGRAPH_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-telegraph-shell', @@ -27,7 +27,7 @@ export class TelegraphShellComponent extends ReadBaseComponent implements OnDest const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.telegraph.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.telegraph.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(TELEGRAPH_PATH), this.tapSaveToHistory(TELEGRAPH_PATH, path), this.tapSaveToCurrentPlaylistItem(TELEGRAPH_PATH, path), this.finalizeLoading()); diff --git a/src/app/telegraph/telegraph.module.ts b/src/app/@site-modules/telegraph/telegraph.module.ts similarity index 88% rename from src/app/telegraph/telegraph.module.ts rename to src/app/@site-modules/telegraph/telegraph.module.ts index 96aa9bd..ea0b591 100644 --- a/src/app/telegraph/telegraph.module.ts +++ b/src/app/@site-modules/telegraph/telegraph.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { TelegraphRoutingModule } from './telegraph-routing.module'; import { TelegraphShellComponent } from './telegraph-shell/telegraph-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/yandere/data-access/yandere.service.ts b/src/app/@site-modules/yandere/data-access/yandere.service.ts similarity index 66% rename from src/app/yandere/data-access/yandere.service.ts rename to src/app/@site-modules/yandere/data-access/yandere.service.ts index 3e3b08c..58616ae 100644 --- a/src/app/yandere/data-access/yandere.service.ts +++ b/src/app/@site-modules/yandere/data-access/yandere.service.ts @@ -1,18 +1,20 @@ import { inject, Injectable } from '@angular/core'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; import { HttpClient } from '@angular/common/http'; import { Observable, map } from 'rxjs'; -import { CompositionEpisode, CompositionPublisher } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { CompositionEpisode } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class YandereService { http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getComposition(id: string): Observable { - return this.http.get(environment.yanderePoolsHost + id) + return this.http.get(this.proxy.proxyUrl(environment.yanderePoolsHost + id)) .pipe(map((data) => { return this.map(data) })) } @@ -29,7 +31,7 @@ export class YandereService { })).filter((i: any) => i.src) .map((img: any) => { return { - src: environment.proxy + Base64.toBase64(img.src), + src: this.proxy.proxyUrl(img.src), width: img.width, height: img.height } diff --git a/src/app/yandere/yandere-routing.module.ts b/src/app/@site-modules/yandere/yandere-routing.module.ts similarity index 100% rename from src/app/yandere/yandere-routing.module.ts rename to src/app/@site-modules/yandere/yandere-routing.module.ts diff --git a/src/app/yandere/yandere-shell/yandere-shell.component.html b/src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.html similarity index 100% rename from src/app/yandere/yandere-shell/yandere-shell.component.html rename to src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.html diff --git a/src/app/zenko/zenko-shell/zenko-shell.component.scss b/src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.scss similarity index 100% rename from src/app/zenko/zenko-shell/zenko-shell.component.scss rename to src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.scss diff --git a/src/app/yandere/yandere-shell/yandere-shell.component.ts b/src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.ts similarity index 84% rename from src/app/yandere/yandere-shell/yandere-shell.component.ts rename to src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.ts index 61b2699..a3c7e9a 100644 --- a/src/app/yandere/yandere-shell/yandere-shell.component.ts +++ b/src/app/@site-modules/yandere/yandere-shell/yandere-shell.component.ts @@ -1,9 +1,9 @@ import { Component, inject, OnDestroy } from '@angular/core'; import { switchMap, of } from 'rxjs'; -import { ReadBaseComponent } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { ReadBaseComponent } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; import { YandereService } from '../data-access/yandere.service'; -import { YANDERE_PATH } from '../../app-routing.module'; +import { YANDERE_PATH } from '../../../app-routing.module'; @Component({ selector: 'app-yandere-shell', @@ -22,7 +22,7 @@ export class YandereShellComponent extends ReadBaseComponent implements OnDestr const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.yandere.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.yandere.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(), this.tapSaveToHistory(YANDERE_PATH, path), this.tapSaveToCurrentPlaylistItem(YANDERE_PATH, path), this.finalizeLoading()); diff --git a/src/app/yandere/yandere.module.ts b/src/app/@site-modules/yandere/yandere.module.ts similarity index 87% rename from src/app/yandere/yandere.module.ts rename to src/app/@site-modules/yandere/yandere.module.ts index 11807a6..b4fe542 100644 --- a/src/app/yandere/yandere.module.ts +++ b/src/app/@site-modules/yandere/yandere.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { YandereRoutingModule } from './yandere-routing.module'; import { YandereShellComponent } from './yandere-shell/yandere-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/zenko/data-access/zenko.service.ts b/src/app/@site-modules/zenko/data-access/zenko.service.ts similarity index 76% rename from src/app/zenko/data-access/zenko.service.ts rename to src/app/@site-modules/zenko/data-access/zenko.service.ts index 0eae702..a4bf265 100644 --- a/src/app/zenko/data-access/zenko.service.ts +++ b/src/app/@site-modules/zenko/data-access/zenko.service.ts @@ -1,15 +1,16 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { Observable, map } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CompositionEpisode, CompositionPublisher } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { environment } from '../../../../environments/environment'; +import { CompositionEpisode, CompositionPublisher } from '../../@common-read'; +import { ProxyService } from '../../../shared/data-access/proxy.service'; @Injectable({ providedIn: 'root' }) export class ZenkoService { http: HttpClient = inject(HttpClient) + proxy: ProxyService = inject(ProxyService) getComposition(id: string): Observable { return this.http.get(environment.zenkoHost + id) @@ -24,7 +25,7 @@ export class ZenkoService { id: data.publisher.id as string, site: `https://zenko.online/teams/`+data.publisher.id as string, name: data.publisher.name as string, - avatar: environment.proxy + Base64.toBase64(`https://zenko.b-cdn.net/${data.publisher.avatar}?optimizer=image&width=900&quality=90&height=auto`) as string, + avatar: this.proxy.proxyUrl(`https://zenko.b-cdn.net/${data.publisher.avatar}?optimizer=image&width=900&quality=90&height=auto`) as string, description: data.publisher.description as string, links: data.publisher.links?.map((l: any) => { return { link: l.link, title: l.title }; }) } as unknown as CompositionPublisher, @@ -33,7 +34,7 @@ export class ZenkoService { return { src: item.imgUrl }; - })).filter((i: any) => i.src).map((img: any) => { return { src: environment.proxy + Base64.toBase64(`https://zenko.b-cdn.net/${img.src}?optimizer=image&width=900&quality=90&height=auto`) } }) + })).filter((i: any) => i.src).map((img: any) => { return { src: this.proxy.proxyUrl(`https://zenko.b-cdn.net/${img.src}?optimizer=image&width=900&quality=90&height=auto`) } }) }; diff --git a/src/app/zenko/zenko-routing.module.ts b/src/app/@site-modules/zenko/zenko-routing.module.ts similarity index 100% rename from src/app/zenko/zenko-routing.module.ts rename to src/app/@site-modules/zenko/zenko-routing.module.ts diff --git a/src/app/zenko/zenko-shell/zenko-shell.component.html b/src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.html similarity index 100% rename from src/app/zenko/zenko-shell/zenko-shell.component.html rename to src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.html diff --git a/src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.scss b/src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/zenko/zenko-shell/zenko-shell.component.ts b/src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.ts similarity index 83% rename from src/app/zenko/zenko-shell/zenko-shell.component.ts rename to src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.ts index 1023de5..3a01ba0 100644 --- a/src/app/zenko/zenko-shell/zenko-shell.component.ts +++ b/src/app/@site-modules/zenko/zenko-shell/zenko-shell.component.ts @@ -1,8 +1,8 @@ import { Component, inject, OnDestroy } from '@angular/core'; import { switchMap, of } from 'rxjs'; -import { ZENKO_PATH } from '../../app-routing.module'; -import { ReadBaseComponent } from '../../common/common-read'; -import { Base64 } from '../../shared/utils'; +import { ZENKO_PATH } from '../../../app-routing.module'; +import { ReadBaseComponent } from '../../@common-read'; +import { Base64 } from '../../../shared/utils'; import { ZenkoService } from '../data-access/zenko.service'; @Component({ @@ -22,7 +22,7 @@ export class ZenkoShellComponent extends ReadBaseComponent implements OnDestroy const path = (Base64.isBase64(pathParam)) ? Base64.fromBase64(pathParam) : pathParam; - return (this.zenko.getComposition(path)).pipe(this.catchError(), this.tapSetTitle(), + return (this.zenko.getComposition(path)).pipe(this.catchError(), this.tapSetMetaTags(ZENKO_PATH), this.tapSaveToHistory(ZENKO_PATH, path), this.tapSaveToCurrentPlaylistItem(ZENKO_PATH, path), this.finalizeLoading()); diff --git a/src/app/zenko/zenko.module.ts b/src/app/@site-modules/zenko/zenko.module.ts similarity index 87% rename from src/app/zenko/zenko.module.ts rename to src/app/@site-modules/zenko/zenko.module.ts index 9789ca3..6cdaa5e 100644 --- a/src/app/zenko/zenko.module.ts +++ b/src/app/@site-modules/zenko/zenko.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'; import { ZenkoRoutingModule } from './zenko-routing.module'; import { ZenkoShellComponent } from './zenko-shell/zenko-shell.component'; -import { CommonReadModule } from '../common/common-read'; +import { CommonReadModule } from '../@common-read'; @NgModule({ diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9ccbf4d..03a91db 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -26,55 +26,62 @@ export const NHENTAI_PATH = `nhentai`; export const COMICK_PATH = `comick`; export const YANDERE_PATH = `yandere`; export const PIXIV_PATH = 'pixiv'; +export const BLANKARY_PATH = 'blankary'; export const FILE_PATH = 'file'; const linkParserMod: LoadChildrenCallback = () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule) -const imgurMod: LoadChildrenCallback = () => import('./imgur/imgur.module').then(m => m.ImgurModule); -const mangadexMod: LoadChildrenCallback = () => import('./mangadex/mangadex.module').then(m => m.MangadexModule); -const telegraphMod = () => import('./telegraph/telegraph.module').then(m => m.TelegraphModule) -const readMod = () => import('./read/read.module').then(m => m.ReadModule); -const redditMod = () => import('./reddit/reddit.module').then(m => m.RedditModule) -const zenkoMod = () => import('./zenko/zenko.module').then(m => m.ZenkoModule) -const nhentaiMod = () => import('./nhentai/nhentai.module').then(m => m.NhentaiModule) -const comickMod = () => import('./comick/comick.module').then(m => m.ComickModule) -const yandereMod = () => import('./yandere/yandere.module').then(m => m.YandereModule) -const pixivMod = () => import('./pixiv/pixiv.module').then(m => m.PixivModule) +const imgurMod: LoadChildrenCallback = () => import('./@site-modules/imgur/imgur.module').then(m => m.ImgurModule); +const mangadexMod: LoadChildrenCallback = () => import('./@site-modules/mangadex/mangadex.module').then(m => m.MangadexModule); +const telegraphMod = () => import('./@site-modules/telegraph/telegraph.module').then(m => m.TelegraphModule) +const readMod = () => import('./@site-modules/read/read.module').then(m => m.ReadModule); +const redditMod = () => import('./@site-modules/reddit/reddit.module').then(m => m.RedditModule) +const zenkoMod = () => import('./@site-modules/zenko/zenko.module').then(m => m.ZenkoModule) +const nhentaiMod = () => import('./@site-modules/nhentai/nhentai.module').then(m => m.NhentaiModule) +const comickMod = () => import('./@site-modules/comick/comick.module').then(m => m.ComickModule) +const yandereMod = () => import('./@site-modules/yandere/yandere.module').then(m => m.YandereModule) +const pixivMod = () => import('./@site-modules/pixiv/pixiv.module').then(m => m.PixivModule) +const blankaryMod = () => import('./@site-modules/blankary/blankary.module').then(m => m.BlankaryModule) const fileMod = () => import('./file/file.module').then(m => m.FileModule) const COMPARE_OUTLET_NAME = 'right' -const moduleMap = new Map() +const siteModulesMap = new Map() + .set(BLANKARY_PATH, blankaryMod) + .set(COMICK_PATH, comickMod) .set(IMGUR_PATH, imgurMod) .set(MANGADEX_PATH, mangadexMod) + .set(NHENTAI_PATH, nhentaiMod) + .set(PIXIV_PATH, pixivMod) + .set(REDDIT_PATH, redditMod) .set(TELEGRAPH_PATH, telegraphMod) + .set(YANDERE_PATH, yandereMod) + .set(ZENKO_PATH, zenkoMod) + .set(READ_PATH, readMod) + +function getPairRoutesToCompare(map: Map) { + const routes: Routes = []; + + for (const item of map) { + routes.push( + { path: item[0], loadChildren: item[1] }, + { outlet: COMPARE_OUTLET_NAME, path: item[0], loadChildren: item[1] } + ) + } + + return routes +} const routes: Routes = [ { path: '', loadChildren: linkParserMod }, { path: LIST_PATH, loadChildren: () => import('./list/list.module').then(m => m.ListModule) }, - { path: IMGUR_PATH, loadChildren: imgurMod }, - { outlet: COMPARE_OUTLET_NAME, path: IMGUR_PATH, loadChildren: imgurMod }, - { path: MANGADEX_PATH, loadChildren: mangadexMod }, - { outlet: COMPARE_OUTLET_NAME, path: MANGADEX_PATH, loadChildren: mangadexMod }, - { path: READ_PATH, loadChildren: readMod }, - { outlet: COMPARE_OUTLET_NAME, path: READ_PATH, loadChildren: readMod }, - { path: TELEGRAPH_PATH, loadChildren: telegraphMod }, - { outlet: COMPARE_OUTLET_NAME, path: TELEGRAPH_PATH, loadChildren: telegraphMod }, - { path: REDDIT_PATH, loadChildren: redditMod }, - { outlet: COMPARE_OUTLET_NAME, path: REDDIT_PATH, loadChildren: redditMod }, - { path: ZENKO_PATH, loadChildren: zenkoMod }, - { outlet: COMPARE_OUTLET_NAME, path: ZENKO_PATH, loadChildren: zenkoMod }, - { path: NHENTAI_PATH, loadChildren: nhentaiMod }, - { outlet: COMPARE_OUTLET_NAME, path: NHENTAI_PATH, loadChildren: nhentaiMod }, - { path: COMICK_PATH, loadChildren: comickMod }, - { outlet: COMPARE_OUTLET_NAME, path: COMICK_PATH, loadChildren: comickMod }, - { path: YANDERE_PATH, loadChildren: yandereMod }, - { outlet: COMPARE_OUTLET_NAME, path: YANDERE_PATH, loadChildren: yandereMod }, - { path: PIXIV_PATH, loadChildren: pixivMod }, - { outlet: COMPARE_OUTLET_NAME, path: PIXIV_PATH, loadChildren: pixivMod }, + ...getPairRoutesToCompare(siteModulesMap), + { path: FILE_PATH, loadChildren: fileMod }, { outlet: COMPARE_OUTLET_NAME, path: FILE_PATH, loadChildren: fileMod }, + { matcher: urlMatcher, loadChildren: linkParserMod }, { outlet: COMPARE_OUTLET_NAME, matcher: urlMatcher, loadChildren: linkParserMod }, + { path: '**', component: PageNotFoundComponent } ]; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index abaa69e..5cd39bc 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,7 @@ -import { Component, HostListener, WritableSignal, inject, signal } from '@angular/core'; +import { Component, HostListener, PLATFORM_ID, WritableSignal, inject, signal } from '@angular/core'; import { LangService } from './shared/data-access/lang.service'; import { ActivatedRoute } from '@angular/router'; -import { DOCUMENT } from '@angular/common'; +import { DOCUMENT, isPlatformBrowser } from '@angular/common'; const SCALE_GAP = 128; @@ -15,9 +15,15 @@ const SCALE_GAP = 128; `] }) export class AppComponent { + platformId = inject(PLATFORM_ID) constructor(public lang: LangService, private route: ActivatedRoute) { this.lang.updateManifest() this.lang.updateTranslate() + + if (isPlatformBrowser(this.platformId) && window.console) { + const msg = `What are you looking for here? The plot twist is in the next volume!` + console.log(`%c${msg}`, "background-color: #166496; color: #ffd60a; font-size: 4rem; font-family: monospace; padding: 8px 16px"); + } } ngOnInit() { diff --git a/src/app/file/file-routing.module.ts b/src/app/file/file-routing.module.ts index 36ea872..e36f683 100644 --- a/src/app/file/file-routing.module.ts +++ b/src/app/file/file-routing.module.ts @@ -10,6 +10,10 @@ const routes: Routes = [ path: 'pdf', loadComponent: () => import('./pdf/pdf.component').then(mod => mod.PdfComponent) }, + { + path: 'mobi', + loadComponent: () => import('./mobi/mobi.component').then(mod => mod.MobiComponent) + } ]; @NgModule({ diff --git a/src/app/file/mobi/mobi.component.html b/src/app/file/mobi/mobi.component.html new file mode 100644 index 0000000..0ec8be5 --- /dev/null +++ b/src/app/file/mobi/mobi.component.html @@ -0,0 +1,5 @@ +@if(episode && episode.images && episode.images.length > 0){ + +} @else { + +} \ No newline at end of file diff --git a/src/app/file/mobi/mobi.component.scss b/src/app/file/mobi/mobi.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/file/mobi/mobi.component.ts b/src/app/file/mobi/mobi.component.ts new file mode 100644 index 0000000..e9a15dc --- /dev/null +++ b/src/app/file/mobi/mobi.component.ts @@ -0,0 +1,75 @@ +import { Component, effect, inject } from '@angular/core'; +import { CompositionEpisode } from '../../@site-modules/@common-read'; +import { Router } from '@angular/router'; +import { FileService } from '../data-access/file.service'; +import { MobiFileReader } from 'readiverse'; +import { SharedModule } from '../../shared/shared.module'; + +@Component({ + selector: 'app-mobi', + standalone: true, + imports: [SharedModule], + templateUrl: './mobi.component.html', + styleUrl: './mobi.component.scss' +}) +export class MobiComponent { + episode: CompositionEpisode | undefined; + router = inject(Router) + fs = inject(FileService) + + constructor() { + effect(() => { this.fileChange(); }); + } + + async openMobi(arrayBuffer: ArrayBuffer) { + const view = new DataView(arrayBuffer) + const mobi = new MobiFileReader(view); + + const td = new TextDecoder("utf-8"); + const html = td.decode(mobi.readText()) + + const dom = new DOMParser().parseFromString(html, 'text/html') + + const meta = mobi.exthHeader.readRecords() as Map + + const title = meta.get(503), author = meta.get(100) + + const images = dom.querySelectorAll('img[recindex]') + const imageIds: { src: string, alt: string }[] = [] + + for (let i = 0; i < images.length; i++) { + const img = images[i]; + const recindex = img.getAttribute('recindex') || '' + const index = parseInt(recindex) + const blob = mobi.readImage(index - 1) + if (blob) { + const src = URL.createObjectURL(blob) + imageIds.push({ src, alt: recindex }) + } + } + + this.episode = { + title: author + ' — ' + title, + images: imageIds + } + + } + + + fileChange() { + const file = this.fs.file(); + + if (file) { + const reader = new FileReader(); + reader.onload = async (e) => { + const arrayBuffer = reader.result as ArrayBuffer; + + await this.openMobi(arrayBuffer) + }; + reader.readAsArrayBuffer(file); + } else { + this.router.navigateByUrl('/') + } + } + +} diff --git a/src/app/file/pdf/pdf.component.ts b/src/app/file/pdf/pdf.component.ts index 2c279e9..8c0ff06 100644 --- a/src/app/file/pdf/pdf.component.ts +++ b/src/app/file/pdf/pdf.component.ts @@ -5,7 +5,7 @@ import { SharedModule } from '../../shared/shared.module'; import { Router } from '@angular/router'; import { getDocument, GlobalWorkerOptions, PDFPageProxy } from 'pdfjs-dist'; import { RenderParameters } from 'pdfjs-dist/types/src/display/api'; -import { CompositionEpisode } from '../../common/common-read'; +import { CompositionEpisode } from '../../@site-modules/@common-read'; GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.min.mjs' diff --git a/src/app/file/zip/zip.component.ts b/src/app/file/zip/zip.component.ts index edee89b..4a421e4 100644 --- a/src/app/file/zip/zip.component.ts +++ b/src/app/file/zip/zip.component.ts @@ -2,7 +2,7 @@ import { Component, effect, inject, OnDestroy, OnInit } from '@angular/core'; import { FileService } from '../data-access/file.service'; import { SharedModule } from '../../shared/shared.module'; import { Router } from '@angular/router'; -import { CompositionEpisode, CompositionImage } from '../../common/common-read'; +import { CompositionEpisode, CompositionImage } from '../../@site-modules/@common-read'; import { DomManipulationService } from '../../shared/data-access'; import { ComicInfo } from '../../shared/utils/comic-info'; import { Acbf } from '../../shared/utils/acbf'; diff --git a/src/app/link-parser/link-parser.module.ts b/src/app/link-parser/link-parser.module.ts index 4117a8d..90cd26e 100644 --- a/src/app/link-parser/link-parser.module.ts +++ b/src/app/link-parser/link-parser.module.ts @@ -10,6 +10,7 @@ import { SettingsComponent } from './ui/settings/settings.component'; import { FooterComponent } from './ui/footer/footer.component'; import { HeaderComponent } from './ui/header/header.component'; import { HistoryModule } from '../history/history.module'; +import { ParserFormComponent } from './ui/parser-form/parser-form.component'; @NgModule({ @@ -18,7 +19,8 @@ import { HistoryModule } from '../history/history.module'; FaqComponent, SettingsComponent, FooterComponent, - HeaderComponent + HeaderComponent, + ParserFormComponent ], imports: [ CommonModule, diff --git a/src/app/link-parser/link-parser/link-parser.component.html b/src/app/link-parser/link-parser/link-parser.component.html index 6e0206b..8047e61 100644 --- a/src/app/link-parser/link-parser/link-parser.component.html +++ b/src/app/link-parser/link-parser/link-parser.component.html @@ -1,32 +1,5 @@
-
-
-

@defer{ }

-
-
- -
- @defer { } -
-
- -
-

{{lang.ph().slogan}}

- @if (linkParams()) { - - {{lang.ph().letsgo}} - - {{linkParams()?.id | truncate}} - - } -
-
- -
- {{lang.ph().createList}} -
- +