Skip to content

Commit 3626b5e

Browse files
authored
Merge pull request #26 from chytanka/develop
Develop
2 parents ecbaf13 + 60a2200 commit 3626b5e

File tree

12 files changed

+286
-115
lines changed

12 files changed

+286
-115
lines changed

src/app/app-routing.module.ts

Lines changed: 48 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NgModule } from '@angular/core';
2-
import { Route, RouterModule, Routes, UrlSegment, UrlSegmentGroup } from '@angular/router';
2+
import { LoadChildrenCallback, Route, RouterModule, Routes, UrlSegment, UrlSegmentGroup } from '@angular/router';
33
import { PageNotFoundComponent } from './page-not-found.component';
44

55
export function urlMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route) {
@@ -28,67 +28,54 @@ export const YANDERE_PATH = `yandere`;
2828
export const PIXIV_PATH = 'pixiv';
2929
export const FILE_PATH = 'file';
3030

31+
const linkParserMod: LoadChildrenCallback = () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule)
32+
const imgurMod: LoadChildrenCallback = () => import('./imgur/imgur.module').then(m => m.ImgurModule);
33+
const mangadexMod: LoadChildrenCallback = () => import('./mangadex/mangadex.module').then(m => m.MangadexModule);
34+
const telegraphMod = () => import('./telegraph/telegraph.module').then(m => m.TelegraphModule)
35+
const readMod = () => import('./read/read.module').then(m => m.ReadModule);
36+
const redditMod = () => import('./reddit/reddit.module').then(m => m.RedditModule)
37+
const zenkoMod = () => import('./zenko/zenko.module').then(m => m.ZenkoModule)
38+
const nhentaiMod = () => import('./nhentai/nhentai.module').then(m => m.NhentaiModule)
39+
const comickMod = () => import('./comick/comick.module').then(m => m.ComickModule)
40+
const yandereMod = () => import('./yandere/yandere.module').then(m => m.YandereModule)
41+
const pixivMod = () => import('./pixiv/pixiv.module').then(m => m.PixivModule)
42+
const fileMod = () => import('./file/file.module').then(m => m.FileModule)
43+
44+
const COMPARE_OUTLET_NAME = 'right'
45+
46+
const moduleMap = new Map<string, LoadChildrenCallback>()
47+
.set(IMGUR_PATH, imgurMod)
48+
.set(MANGADEX_PATH, mangadexMod)
49+
.set(TELEGRAPH_PATH, telegraphMod)
50+
3151
const routes: Routes = [
32-
{
33-
path: '',
34-
loadChildren: () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule)
35-
},
36-
{
37-
path: LIST_PATH,
38-
loadChildren: () => import('./list/list.module').then(m => m.ListModule)
39-
},
40-
{
41-
path: IMGUR_PATH,
42-
loadChildren: () => import('./imgur/imgur.module').then(m => m.ImgurModule)
43-
},
44-
{
45-
path: MANGADEX_PATH,
46-
loadChildren: () => import('./mangadex/mangadex.module').then(m => m.MangadexModule)
47-
},
48-
{
49-
path: READ_PATH,
50-
loadChildren: () => import('./read/read.module').then(m => m.ReadModule)
51-
},
52-
{
53-
path: TELEGRAPH_PATH,
54-
loadChildren: () => import('./telegraph/telegraph.module').then(m => m.TelegraphModule)
55-
},
56-
{
57-
path: REDDIT_PATH,
58-
loadChildren: () => import('./reddit/reddit.module').then(m => m.RedditModule)
59-
},
60-
{
61-
path: ZENKO_PATH,
62-
loadChildren: () => import('./zenko/zenko.module').then(m => m.ZenkoModule)
63-
},
64-
{
65-
path: NHENTAI_PATH,
66-
loadChildren: () => import('./nhentai/nhentai.module').then(m => m.NhentaiModule)
67-
},
68-
{
69-
path: COMICK_PATH,
70-
loadChildren: () => import('./comick/comick.module').then(m => m.ComickModule)
71-
},
72-
{
73-
path: YANDERE_PATH,
74-
loadChildren: () => import('./yandere/yandere.module').then(m => m.YandereModule)
75-
},
76-
{
77-
path: PIXIV_PATH,
78-
loadChildren: () => import('./pixiv/pixiv.module').then(m => m.PixivModule)
79-
},
80-
{
81-
path: FILE_PATH,
82-
loadChildren: () => import('./file/file.module').then(m => m.FileModule)
83-
},
84-
{
85-
matcher: urlMatcher,
86-
loadChildren: () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule)
87-
},
88-
{
89-
path: '**',
90-
component: PageNotFoundComponent
91-
}
52+
{ path: '', loadChildren: linkParserMod },
53+
{ path: LIST_PATH, loadChildren: () => import('./list/list.module').then(m => m.ListModule) },
54+
{ path: IMGUR_PATH, loadChildren: imgurMod },
55+
{ outlet: COMPARE_OUTLET_NAME, path: IMGUR_PATH, loadChildren: imgurMod },
56+
{ path: MANGADEX_PATH, loadChildren: mangadexMod },
57+
{ outlet: COMPARE_OUTLET_NAME, path: MANGADEX_PATH, loadChildren: mangadexMod },
58+
{ path: READ_PATH, loadChildren: readMod },
59+
{ outlet: COMPARE_OUTLET_NAME, path: READ_PATH, loadChildren: readMod },
60+
{ path: TELEGRAPH_PATH, loadChildren: telegraphMod },
61+
{ outlet: COMPARE_OUTLET_NAME, path: TELEGRAPH_PATH, loadChildren: telegraphMod },
62+
{ path: REDDIT_PATH, loadChildren: redditMod },
63+
{ outlet: COMPARE_OUTLET_NAME, path: REDDIT_PATH, loadChildren: redditMod },
64+
{ path: ZENKO_PATH, loadChildren: zenkoMod },
65+
{ outlet: COMPARE_OUTLET_NAME, path: ZENKO_PATH, loadChildren: zenkoMod },
66+
{ path: NHENTAI_PATH, loadChildren: nhentaiMod },
67+
{ outlet: COMPARE_OUTLET_NAME, path: NHENTAI_PATH, loadChildren: nhentaiMod },
68+
{ path: COMICK_PATH, loadChildren: comickMod },
69+
{ outlet: COMPARE_OUTLET_NAME, path: COMICK_PATH, loadChildren: comickMod },
70+
{ path: YANDERE_PATH, loadChildren: yandereMod },
71+
{ outlet: COMPARE_OUTLET_NAME, path: YANDERE_PATH, loadChildren: yandereMod },
72+
{ path: PIXIV_PATH, loadChildren: pixivMod },
73+
{ outlet: COMPARE_OUTLET_NAME, path: PIXIV_PATH, loadChildren: pixivMod },
74+
{ path: FILE_PATH, loadChildren: fileMod },
75+
{ outlet: COMPARE_OUTLET_NAME, path: FILE_PATH, loadChildren: fileMod },
76+
{ matcher: urlMatcher, loadChildren: linkParserMod },
77+
{ outlet: COMPARE_OUTLET_NAME, matcher: urlMatcher, loadChildren: linkParserMod },
78+
{ path: '**', component: PageNotFoundComponent }
9279
];
9380

9481
@NgModule({

src/app/app.component.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ const SCALE_GAP = 128;
77

88
@Component({
99
selector: 'app-root',
10-
template: `<router-outlet></router-outlet>`
10+
template: `<div><router-outlet></router-outlet></div><div><router-outlet name="right"></router-outlet></div>`,
11+
styles: [`
12+
// :host {
13+
// display: flex;
14+
// }
15+
`]
1116
})
1217
export class AppComponent {
1318
constructor(public lang: LangService, private route: ActivatedRoute) {
@@ -26,7 +31,7 @@ export class AppComponent {
2631
}
2732
})
2833
}
29-
34+
3035
private readonly document = inject(DOCUMENT);
3136

3237
@HostListener('window:resize')

src/app/file/data-access/zip.worker.ts

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,36 @@ addEventListener('message', ({ data }) => {
99

1010
zip.loadAsync(arrayBuffer)
1111
.then(async zip => {
12-
const filePromises: any = [];
13-
const images = filterImages(Object.keys(zip.files)).sort()
12+
const filesName: string[] = Object.keys(zip.files);
1413

15-
postMessage({ type: 'zipopen', data: {
16-
count: images.length
17-
} });
14+
console.dir(zip.files)
15+
16+
const comicInfoFile = getComicInfoFile(filesName)
17+
18+
if (comicInfoFile) {
19+
const comicinfo = zip.files[comicInfoFile]
20+
await comicinfo.async('text').then(text => { postMessage({ type: 'comicinfo', data: text }); })
21+
}
22+
23+
const acbf = getAcbfFile(filesName)
24+
if (acbf) {
25+
const acbfF = zip.files[acbf]
26+
await acbfF.async('text').then(text => { postMessage({ type: 'acbf', data: text }); })
27+
}
28+
29+
const images = filterImages(filesName).sort()
30+
postMessage({ type: 'zipopen', data: { count: images.length } });
1831

1932
for (let i = 0; i < images.length; i++) {
2033
const filename = images[i];
2134

22-
const filePromise = await zip.files[filename].async('blob').then(blob => {
35+
await zip.files[filename].async('blob').then(blob => {
2336
const url = URL.createObjectURL(blob);
2437
postMessage({ type: 'file', url: url, index: i });
25-
postMessage({ type: 'progress', progress: [i, images.length] });
2638
});
27-
28-
filePromises.push(filePromise);
2939
}
3040

31-
Promise.all(filePromises).then(() => {
32-
postMessage({ type: 'complete', progress: [images.length, images.length] });
33-
});
41+
3442
});
3543
});
3644

@@ -41,4 +49,21 @@ function filterImages(fileList: Array<string>) {
4149
const extension = file.substring(file.lastIndexOf('.')).toLowerCase();
4250
return imageExtensions.includes(extension);
4351
});
52+
}
53+
54+
function getComicInfoFile(fileList: Array<string>) {
55+
const resultArray = fileList.filter(f => f.toLowerCase() == 'comicinfo.xml')
56+
57+
return resultArray.length > 0 ? resultArray[0] : false
58+
}
59+
60+
function getAcbfFile(fileList: Array<string>) {
61+
const imageExtensions = ['.acbf'];
62+
63+
const result = fileList.filter(file => {
64+
const extension = file.substring(file.lastIndexOf('.')).toLowerCase();
65+
return imageExtensions.includes(extension);
66+
})
67+
68+
return result.length > 0 ? result[0] : null;
4469
}

src/app/file/pdf/pdf.component.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { CompositionEpisode } from '../../common/common-read';
99

1010
GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.min.mjs'
1111

12+
const MDASH = '—';
13+
1214
@Component({
1315
selector: 'app-pdf',
1416
standalone: true,
@@ -31,8 +33,14 @@ export class PdfComponent {
3133
disableFontFace: true,
3234
}).promise;
3335

36+
const meta = await pdf.getMetadata()
37+
const title = (meta.info as any)['Title']
38+
const author = (meta.info as any)['Author']
39+
40+
console.dir(meta.info)
41+
3442
this.episode = {
35-
title: this.fs.file()?.name ?? '',
43+
title: title ? (author ? author + ` ${MDASH} ` : '') + title : this.fs.file()?.name ?? '',
3644
images: [...Array(pdf.numPages)].map((item: any, index) => { return { src: index + '' } })
3745
}
3846

@@ -82,5 +90,5 @@ export class PdfComponent {
8290
}
8391
}
8492

85-
93+
8694
}

src/app/file/zip/zip.component.ts

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { FileService } from '../data-access/file.service';
33
import { SharedModule } from '../../shared/shared.module';
44
import { Router } from '@angular/router';
55
import { CompositionEpisode, CompositionImage } from '../../common/common-read';
6+
import { DomManipulationService } from '../../shared/data-access';
7+
import { ComicInfo } from '../../shared/utils/comic-info';
8+
import { Acbf } from '../../shared/utils/acbf';
69

710
@Component({
811
selector: 'app-zip',
@@ -12,13 +15,12 @@ import { CompositionEpisode, CompositionImage } from '../../common/common-read';
1215
styleUrl: './zip.component.scss'
1316
})
1417
export class ZipComponent implements OnInit, OnDestroy {
15-
episode: CompositionEpisode | undefined;
16-
17-
progress: number = 0;
1818
private worker!: Worker;
19+
20+
episode: CompositionEpisode | undefined;
1921

2022
router = inject(Router)
21-
23+
dm = inject(DomManipulationService)
2224
fs = inject(FileService)
2325

2426
constructor() {
@@ -38,38 +40,57 @@ export class ZipComponent implements OnInit, OnDestroy {
3840
this.worker.terminate();
3941
}
4042

43+
private workerHandlers = new Map<string, Function>()
44+
.set('comicinfo', this.comicinfoHandler.bind(this))
45+
.set('zipopen', this.zipopenHandler.bind(this))
46+
.set('file', this.fileHandler.bind(this))
47+
.set('acbf', this.acbfHandler.bind(this))
48+
49+
50+
private acbfHandler(msg: any) {
51+
const acbf = new Acbf(msg.data)
52+
53+
}
54+
55+
private comicinfoHandler(msg: any) {
56+
const comicInfo = new ComicInfo(msg.data)
57+
58+
if (this.episode && comicInfo.title) {
59+
this.episode.title = comicInfo.title
60+
this.episode.volume = parseInt(comicInfo.volume ?? '')
61+
}
62+
63+
}
64+
65+
private zipopenHandler(msg: any) {
66+
const imgs: CompositionImage[] = [...Array(msg.data.count)].map((item: CompositionImage, index) => { return { src: `?id=${index}` } });
67+
68+
if (this.episode) {
69+
this.episode.images = imgs
70+
}
71+
}
72+
private fileHandler(msg: any) {
73+
const { index, url } = msg;
74+
75+
if (this.episode)
76+
this.episode.images[index].src = url
77+
}
78+
4179
initZipWorker() {
4280
this.terminateWorker()
43-
if (typeof Worker !== 'undefined') {
4481

82+
if (typeof Worker !== 'undefined') {
4583
this.worker = new Worker(new URL('../data-access/zip.worker', import.meta.url));
4684
this.worker.onmessage = ({ data }) => {
47-
if (data.type === 'progress') {
48-
this.progress = data.progress;
49-
} else if (data.type === 'file') {
50-
``
51-
const { index, url } = data;
52-
53-
if (this.episode)
54-
this.episode.images[index].src = url
55-
} else if (data.type === 'complete') {
56-
this.progress = data.progress;
57-
}
58-
else if (data.type === 'zipopen') {
59-
const imgs: CompositionImage[] = [...Array(data.data.count)].map((item: CompositionImage, index) => { return { src: `?id=${index}` } });
60-
61-
if (this.episode) {
62-
this.episode.images = imgs
63-
}
64-
}
85+
const fn = this.workerHandlers.get(data.type)
86+
if (fn) fn(data)
6587
};
6688
} else {
6789
console.error('Web Workers are not supported in this environment.');
6890
}
6991
}
7092

7193
fileChange() {
72-
// this.images = []
7394
const file = this.fs.file();
7495
if (file && this.worker) {
7596
const reader = new FileReader();

src/app/reddit/data-access/reddit.service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
33
import { Observable, map } from 'rxjs';
44
import { environment } from '../../../environments/environment';
55
import { CompositionEpisode } from '../../common/common-read';
6+
import { Base64 } from '../../shared/utils';
67

78
@Injectable({
89
providedIn: 'root'
@@ -29,8 +30,9 @@ export class RedditService {
2930
nsfw: post.thumbnail == "nsfw" || post.over_18,
3031
images: imgs.map((i: any): any => {
3132
const ext = (media_metadata[i.media_id]?.m).replace('image/', '');
33+
const imgSrc = `https://i.redd.it/${i.media_id}.${ext ?? 'jpg'}`
3234
return {
33-
src: `https://i.redd.it/${i.media_id}.${ext ?? 'jpg'}`,
35+
src: environment.proxy + Base64.toBase64(imgSrc),
3436
height: (media_metadata[i.media_id]?.s).y,
3537
width: (media_metadata[i.media_id]?.s).x,
3638
}

src/app/shared/data-access/dom-manipulation.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export class DomManipulationService {
1212

1313
constructor() { }
1414

15+
getTextByTagName(doc: Document, tagName: string) {
16+
return doc.getElementsByTagName(tagName)[0]?.textContent;
17+
}
18+
1519
toggleFullScreen(el: HTMLElement) {
1620
if (!this.document.fullscreenElement) {
1721
if (el.requestFullscreen) {

0 commit comments

Comments
 (0)