-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from chytanka/develop
Read by link to JSON, Save User settings, Base64 in URL
- Loading branch information
Showing
29 changed files
with
563 additions
and
235 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,24 @@ | ||
<app-viewer *ngIf="(episode$ | async) as episode" [episode]="episode"> | ||
@if(episode$ | async; as episode){ | ||
<app-viewer [episode]="episode"> | ||
<div style="direction: ltr; user-select: text !important; text-wrap: balance; padding: 1rem; text-align: center; display: grid; | ||
place-content: center; | ||
justify-items: center; min-height: 50vh;"> | ||
<a href="https://imgur.com" target="_blank" rel="noopener noreferrer" style="display: flex; gap: 1ch; "> | ||
<img src="/assets/logos/imgur-logo.svg" alt="Imgur logo"> | ||
</a> | ||
<p>{{lang.phrases.imagesVia}}<a href="https://imgur.com" target="_blank" rel="noopener noreferrer">Imgur</a> API. | ||
<p>{{lang.phrases.imagesVia}}<a href="https://imgur.com" target="_blank" rel="noopener noreferrer">Imgur</a> | ||
API. | ||
{{lang.phrases.thanks}}<br>{{lang.phrases.detalisCopy}}</p> | ||
</div> | ||
</app-viewer> | ||
<div *ngIf="error$ | async as error" class="error-message"> | ||
} | ||
@if(error$ | async; as error){ | ||
<div class="error-message"> | ||
{{ error }} <br> | ||
<button (click)="refreshData()">Ше раз</button> <br> | ||
<a [routerLink]="'/'">🏠</a> | ||
</div> | ||
<div *ngIf="loading$ | async as loading" class="loading"> | ||
⏳ | ||
</div> | ||
} | ||
@if(loading$ | async; as loading){ | ||
<div class="loading">⏳</div> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,27 @@ | ||
import { Component, OnDestroy, WritableSignal, signal } from '@angular/core'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
import { Component } from '@angular/core'; | ||
import { ImgurService } from '../data-access/imgur.service'; | ||
import { CompositionEpisode } from '../../shared/utils'; | ||
import { BehaviorSubject, Subject, catchError, finalize, forkJoin, of, switchMap, takeUntil } from 'rxjs'; | ||
import { LangService } from '../../shared/data-access/lang.service'; | ||
import { Base64, ReadBaseComponent } from '../../shared/utils'; | ||
import { of, switchMap } from 'rxjs'; | ||
|
||
@Component({ | ||
selector: 'app-imgur-shell', | ||
templateUrl: './imgur-shell.component.html', | ||
styleUrl: './imgur-shell.component.scss' | ||
}) | ||
export class ImgurShellComponent { | ||
error$ = new BehaviorSubject<string | null>(null); | ||
loading$ = new BehaviorSubject<boolean>(false); | ||
export class ImgurShellComponent extends ReadBaseComponent { | ||
|
||
episode$ = this.route.paramMap.pipe( | ||
switchMap(params => { | ||
const id = params?.get('id'); | ||
override episode$ = this.combineParamMapAndRefresh() | ||
.pipe(this.tapStartLoading(), | ||
switchMap(([params]) => { | ||
const idParam = params?.get('id'); | ||
|
||
if (!id) return of(null); | ||
if (!idParam) return of(null); | ||
|
||
this.loading$.next(true); | ||
const id = (Base64.isBase64(idParam)) ? Base64.fromBase64(idParam) : idParam; | ||
|
||
return (this.imgur.getComposition(id)).pipe( | ||
catchError(() => { | ||
this.error$.next(this.lang.phrases.dataLoadErr); | ||
return (this.imgur.getComposition(id)).pipe(this.catchError(), this.tapSetTitle(), this.finalizeLoading()); | ||
}) | ||
); | ||
|
||
return of(null); | ||
}), | ||
finalize(() => this.loading$.next(false)) | ||
); | ||
}) | ||
); | ||
|
||
constructor(private route: ActivatedRoute, public imgur: ImgurService, public lang: LangService) { } | ||
constructor(public imgur: ImgurService) { super() } | ||
} |
198 changes: 117 additions & 81 deletions
198
src/app/link-parser/link-parser/link-parser.component.html
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './link-parser'; | ||
export * from './imgur-link-parser'; | ||
export * from './mangadex-link-parser'; | ||
export * from './mangadex-link-parser'; | ||
export * from './json-link-parser'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { LinkParser } from "./link-parser"; | ||
|
||
export class JsonLinkParser extends LinkParser { | ||
override regex = /((?:https?:\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b[-a-zA-Z0-9()@:%_\+.~#?&//=]*)/; | ||
override site = 'read' | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 36 additions & 74 deletions
110
src/app/mangadex/mangadex-shell/mangadex-shell.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,45 @@ | ||
import { Component } from '@angular/core'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
import { BehaviorSubject, Observable, catchError, finalize, forkJoin, map, of, switchMap, tap, throwError } from 'rxjs'; | ||
import { forkJoin, map, of, switchMap } from 'rxjs'; | ||
import { MangadexService } from '../data-access/mangadex.service'; | ||
import { Title } from '@angular/platform-browser'; | ||
import { Base64, ReadBaseComponent } from '../../shared/utils'; | ||
|
||
@Component({ | ||
selector: 'app-mangadex-shell', | ||
templateUrl: './mangadex-shell.component.html', | ||
styleUrl: './mangadex-shell.component.scss' | ||
}) | ||
export class MangadexShellComponent { | ||
error$ = new BehaviorSubject<string | null>(null); | ||
loading$ = new BehaviorSubject<boolean>(false); | ||
|
||
// episode$ = this.route.paramMap.pipe( | ||
// switchMap(params => { | ||
// const id = params?.get('id'); | ||
|
||
// if (!id) return of(null); | ||
|
||
// this.loading$.next(true); | ||
|
||
// const ch$ = this.mangadex.getChapter(id); | ||
// const imgs$ = this.mangadex.getChapterImages(id); | ||
|
||
// return forkJoin([ch$, imgs$]).pipe( | ||
// map(([ch, imgs]) => { | ||
// ch.images = imgs; | ||
// return ch | ||
// }), | ||
// tap(episode=>{ | ||
// this.title.setTitle(`${episode.title} | Chytanka`) | ||
// }), | ||
// catchError(() => { | ||
// this.error$.next('Data loading error. Please try again later.'); | ||
|
||
// return of(null); | ||
// }), | ||
// finalize(() => this.loading$.next(false)) | ||
// ); | ||
// }) | ||
// ); | ||
|
||
episode$ = this.route.paramMap.pipe( | ||
switchMap(params => { | ||
const id = params?.get('id'); | ||
|
||
if (!id) return of(null); | ||
|
||
this.loading$.next(true); | ||
|
||
const ch$ = this.mangadex.getChapter(id); | ||
|
||
return ch$.pipe( | ||
switchMap(ch => { | ||
const imgs$ = this.mangadex.getChapterImages(id); | ||
const manga$ = (ch.mangaId)? this.mangadex.getManga(ch.mangaId): of(null); | ||
|
||
return forkJoin([imgs$, manga$]).pipe( | ||
map(([imgs, manga]) => { | ||
ch.images = imgs; | ||
ch.nsfw = manga?.nsfw ?? undefined; | ||
return ch; | ||
}), | ||
catchError(() => { | ||
this.error$.next('Data loading error. Please try again later.'); | ||
return of(null); | ||
}) | ||
); | ||
}), | ||
tap(episode => { | ||
if (episode) { | ||
this.title.setTitle(`${episode.title} | Chytanka`); | ||
} | ||
}), | ||
finalize(() => this.loading$.next(false)) | ||
); | ||
}) | ||
); | ||
|
||
constructor(private route: ActivatedRoute, public mangadex: MangadexService, private title: Title) { } | ||
export class MangadexShellComponent extends ReadBaseComponent { | ||
|
||
override episode$ = this.combineParamMapAndRefresh() | ||
.pipe(this.tapStartLoading(), | ||
switchMap(([params]) => { | ||
const idParam = params?.get('id'); | ||
|
||
if (!idParam) return of(null); | ||
|
||
const id = (Base64.isBase64(idParam)) ? Base64.fromBase64(idParam) : idParam; | ||
const ch$ = this.mangadex.getChapter(id); | ||
|
||
return ch$.pipe( | ||
switchMap(ch => { | ||
const imgs$ = this.mangadex.getChapterImages(id); | ||
const manga$ = (ch.mangaId) ? this.mangadex.getManga(ch.mangaId) : of(null); | ||
|
||
return forkJoin([imgs$, manga$]).pipe( | ||
map(([imgs, manga]) => { | ||
ch.images = imgs; | ||
ch.nsfw = manga?.nsfw ?? undefined; | ||
return ch; | ||
}), | ||
this.catchError() | ||
); | ||
}), | ||
this.catchError(), | ||
this.tapSetTitle(), | ||
this.finalizeLoading() | ||
); | ||
}) | ||
); | ||
|
||
constructor(public mangadex: MangadexService) { super() } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { HttpClient } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { Observable, catchError, tap, throwError } from 'rxjs'; | ||
import { CompositionEpisode, isCompositionEpisode } from '../../shared/utils'; | ||
|
||
@Injectable({ | ||
providedIn: 'root' | ||
}) | ||
export class ReadService { | ||
|
||
constructor(private http: HttpClient) { } | ||
|
||
getComposition(url: string): Observable<CompositionEpisode> { | ||
return this.http.get<CompositionEpisode>(url) | ||
.pipe( | ||
tap(data => { if (!isCompositionEpisode(data)) throw new Error() }), | ||
catchError(error => throwError(() => error)) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { RouterModule, Routes } from '@angular/router'; | ||
import { ReadShellComponent } from './read-shell/read-shell.component'; | ||
|
||
const routes: Routes = [ | ||
{ path: '', redirectTo: '/', pathMatch: 'full' }, | ||
{ | ||
path: ':url', | ||
component: ReadShellComponent | ||
} | ||
]; | ||
|
||
@NgModule({ | ||
imports: [RouterModule.forChild(routes)], | ||
exports: [RouterModule] | ||
}) | ||
export class ReadRoutingModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@if(episode$ | async; as episode){ | ||
<app-viewer [episode]="episode"> | ||
<div style="direction: ltr; user-select: text !important; text-wrap: balance; padding: 1rem; text-align: center; display: grid; | ||
place-content: center; | ||
justify-items: center; min-height: 50vh;"> | ||
<p>End of episode</p><br> | ||
<a [routerLink]="'/'"> | ||
<h2>🏠</h2> | ||
</a> | ||
</div> | ||
</app-viewer> | ||
} | ||
@if(error$ | async; as error){ | ||
<div class="error-message"> | ||
{{ error }} <br> | ||
<button (click)="refreshData()">Ше раз</button> <br> | ||
<a [routerLink]="'/'">🏠</a> | ||
</div> | ||
} | ||
@if(loading$ | async; as loading){ | ||
<div class="loading">⏳</div> | ||
} |
Empty file.
Oops, something went wrong.