Skip to content

Commit

Permalink
Merge pull request #26 from chytanka/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rodzyk authored Sep 26, 2024
2 parents ecbaf13 + 60a2200 commit 3626b5e
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 115 deletions.
109 changes: 48 additions & 61 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NgModule } from '@angular/core';
import { Route, RouterModule, Routes, UrlSegment, UrlSegmentGroup } from '@angular/router';
import { LoadChildrenCallback, Route, RouterModule, Routes, UrlSegment, UrlSegmentGroup } from '@angular/router';
import { PageNotFoundComponent } from './page-not-found.component';

export function urlMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route) {
Expand Down Expand Up @@ -28,67 +28,54 @@ export const YANDERE_PATH = `yandere`;
export const PIXIV_PATH = 'pixiv';
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 fileMod = () => import('./file/file.module').then(m => m.FileModule)

const COMPARE_OUTLET_NAME = 'right'

const moduleMap = new Map<string, LoadChildrenCallback>()
.set(IMGUR_PATH, imgurMod)
.set(MANGADEX_PATH, mangadexMod)
.set(TELEGRAPH_PATH, telegraphMod)

const routes: Routes = [
{
path: '',
loadChildren: () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule)
},
{
path: LIST_PATH,
loadChildren: () => import('./list/list.module').then(m => m.ListModule)
},
{
path: IMGUR_PATH,
loadChildren: () => import('./imgur/imgur.module').then(m => m.ImgurModule)
},
{
path: MANGADEX_PATH,
loadChildren: () => import('./mangadex/mangadex.module').then(m => m.MangadexModule)
},
{
path: READ_PATH,
loadChildren: () => import('./read/read.module').then(m => m.ReadModule)
},
{
path: TELEGRAPH_PATH,
loadChildren: () => import('./telegraph/telegraph.module').then(m => m.TelegraphModule)
},
{
path: REDDIT_PATH,
loadChildren: () => import('./reddit/reddit.module').then(m => m.RedditModule)
},
{
path: ZENKO_PATH,
loadChildren: () => import('./zenko/zenko.module').then(m => m.ZenkoModule)
},
{
path: NHENTAI_PATH,
loadChildren: () => import('./nhentai/nhentai.module').then(m => m.NhentaiModule)
},
{
path: COMICK_PATH,
loadChildren: () => import('./comick/comick.module').then(m => m.ComickModule)
},
{
path: YANDERE_PATH,
loadChildren: () => import('./yandere/yandere.module').then(m => m.YandereModule)
},
{
path: PIXIV_PATH,
loadChildren: () => import('./pixiv/pixiv.module').then(m => m.PixivModule)
},
{
path: FILE_PATH,
loadChildren: () => import('./file/file.module').then(m => m.FileModule)
},
{
matcher: urlMatcher,
loadChildren: () => import('./link-parser/link-parser.module').then(m => m.LinkParserModule)
},
{
path: '**',
component: PageNotFoundComponent
}
{ 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 },
{ 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 }
];

@NgModule({
Expand Down
9 changes: 7 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ const SCALE_GAP = 128;

@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
template: `<div><router-outlet></router-outlet></div><div><router-outlet name="right"></router-outlet></div>`,
styles: [`
// :host {
// display: flex;
// }
`]
})
export class AppComponent {
constructor(public lang: LangService, private route: ActivatedRoute) {
Expand All @@ -26,7 +31,7 @@ export class AppComponent {
}
})
}

private readonly document = inject(DOCUMENT);

@HostListener('window:resize')
Expand Down
49 changes: 37 additions & 12 deletions src/app/file/data-access/zip.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,36 @@ addEventListener('message', ({ data }) => {

zip.loadAsync(arrayBuffer)
.then(async zip => {
const filePromises: any = [];
const images = filterImages(Object.keys(zip.files)).sort()
const filesName: string[] = Object.keys(zip.files);

postMessage({ type: 'zipopen', data: {
count: images.length
} });
console.dir(zip.files)

const comicInfoFile = getComicInfoFile(filesName)

if (comicInfoFile) {
const comicinfo = zip.files[comicInfoFile]
await comicinfo.async('text').then(text => { postMessage({ type: 'comicinfo', data: text }); })
}

const acbf = getAcbfFile(filesName)
if (acbf) {
const acbfF = zip.files[acbf]
await acbfF.async('text').then(text => { postMessage({ type: 'acbf', data: text }); })
}

const images = filterImages(filesName).sort()
postMessage({ type: 'zipopen', data: { count: images.length } });

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

const filePromise = await zip.files[filename].async('blob').then(blob => {
await zip.files[filename].async('blob').then(blob => {
const url = URL.createObjectURL(blob);
postMessage({ type: 'file', url: url, index: i });
postMessage({ type: 'progress', progress: [i, images.length] });
});

filePromises.push(filePromise);
}

Promise.all(filePromises).then(() => {
postMessage({ type: 'complete', progress: [images.length, images.length] });
});

});
});

Expand All @@ -41,4 +49,21 @@ function filterImages(fileList: Array<string>) {
const extension = file.substring(file.lastIndexOf('.')).toLowerCase();
return imageExtensions.includes(extension);
});
}

function getComicInfoFile(fileList: Array<string>) {
const resultArray = fileList.filter(f => f.toLowerCase() == 'comicinfo.xml')

return resultArray.length > 0 ? resultArray[0] : false
}

function getAcbfFile(fileList: Array<string>) {
const imageExtensions = ['.acbf'];

const result = fileList.filter(file => {
const extension = file.substring(file.lastIndexOf('.')).toLowerCase();
return imageExtensions.includes(extension);
})

return result.length > 0 ? result[0] : null;
}
12 changes: 10 additions & 2 deletions src/app/file/pdf/pdf.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { CompositionEpisode } from '../../common/common-read';

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

const MDASH = '—';

@Component({
selector: 'app-pdf',
standalone: true,
Expand All @@ -31,8 +33,14 @@ export class PdfComponent {
disableFontFace: true,
}).promise;

const meta = await pdf.getMetadata()
const title = (meta.info as any)['Title']
const author = (meta.info as any)['Author']

console.dir(meta.info)

this.episode = {
title: this.fs.file()?.name ?? '',
title: title ? (author ? author + ` ${MDASH} ` : '') + title : this.fs.file()?.name ?? '',
images: [...Array(pdf.numPages)].map((item: any, index) => { return { src: index + '' } })
}

Expand Down Expand Up @@ -82,5 +90,5 @@ export class PdfComponent {
}
}


}
69 changes: 45 additions & 24 deletions src/app/file/zip/zip.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ 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 { DomManipulationService } from '../../shared/data-access';
import { ComicInfo } from '../../shared/utils/comic-info';
import { Acbf } from '../../shared/utils/acbf';

@Component({
selector: 'app-zip',
Expand All @@ -12,13 +15,12 @@ import { CompositionEpisode, CompositionImage } from '../../common/common-read';
styleUrl: './zip.component.scss'
})
export class ZipComponent implements OnInit, OnDestroy {
episode: CompositionEpisode | undefined;

progress: number = 0;
private worker!: Worker;

episode: CompositionEpisode | undefined;

router = inject(Router)

dm = inject(DomManipulationService)
fs = inject(FileService)

constructor() {
Expand All @@ -38,38 +40,57 @@ export class ZipComponent implements OnInit, OnDestroy {
this.worker.terminate();
}

private workerHandlers = new Map<string, Function>()
.set('comicinfo', this.comicinfoHandler.bind(this))
.set('zipopen', this.zipopenHandler.bind(this))
.set('file', this.fileHandler.bind(this))
.set('acbf', this.acbfHandler.bind(this))


private acbfHandler(msg: any) {
const acbf = new Acbf(msg.data)

}

private comicinfoHandler(msg: any) {
const comicInfo = new ComicInfo(msg.data)

if (this.episode && comicInfo.title) {
this.episode.title = comicInfo.title
this.episode.volume = parseInt(comicInfo.volume ?? '')
}

}

private zipopenHandler(msg: any) {
const imgs: CompositionImage[] = [...Array(msg.data.count)].map((item: CompositionImage, index) => { return { src: `?id=${index}` } });

if (this.episode) {
this.episode.images = imgs
}
}
private fileHandler(msg: any) {
const { index, url } = msg;

if (this.episode)
this.episode.images[index].src = url
}

initZipWorker() {
this.terminateWorker()
if (typeof Worker !== 'undefined') {

if (typeof Worker !== 'undefined') {
this.worker = new Worker(new URL('../data-access/zip.worker', import.meta.url));
this.worker.onmessage = ({ data }) => {
if (data.type === 'progress') {
this.progress = data.progress;
} else if (data.type === 'file') {
``
const { index, url } = data;

if (this.episode)
this.episode.images[index].src = url
} else if (data.type === 'complete') {
this.progress = data.progress;
}
else if (data.type === 'zipopen') {
const imgs: CompositionImage[] = [...Array(data.data.count)].map((item: CompositionImage, index) => { return { src: `?id=${index}` } });

if (this.episode) {
this.episode.images = imgs
}
}
const fn = this.workerHandlers.get(data.type)
if (fn) fn(data)
};
} else {
console.error('Web Workers are not supported in this environment.');
}
}

fileChange() {
// this.images = []
const file = this.fs.file();
if (file && this.worker) {
const reader = new FileReader();
Expand Down
4 changes: 3 additions & 1 deletion src/app/reddit/data-access/reddit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { 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';

@Injectable({
providedIn: 'root'
Expand All @@ -29,8 +30,9 @@ export class RedditService {
nsfw: post.thumbnail == "nsfw" || post.over_18,
images: imgs.map((i: any): any => {
const ext = (media_metadata[i.media_id]?.m).replace('image/', '');
const imgSrc = `https://i.redd.it/${i.media_id}.${ext ?? 'jpg'}`
return {
src: `https://i.redd.it/${i.media_id}.${ext ?? 'jpg'}`,
src: environment.proxy + Base64.toBase64(imgSrc),
height: (media_metadata[i.media_id]?.s).y,
width: (media_metadata[i.media_id]?.s).x,
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/shared/data-access/dom-manipulation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class DomManipulationService {

constructor() { }

getTextByTagName(doc: Document, tagName: string) {
return doc.getElementsByTagName(tagName)[0]?.textContent;
}

toggleFullScreen(el: HTMLElement) {
if (!this.document.fullscreenElement) {
if (el.requestFullscreen) {
Expand Down
Loading

0 comments on commit 3626b5e

Please sign in to comment.