mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-04-19 14:53:20 +02:00
162 lines
6.8 KiB
TypeScript
162 lines
6.8 KiB
TypeScript
import Manga from "../Manga";
|
|
import React, {ReactElement, ReactEventHandler, useEffect} from "react";
|
|
import Icon from '@mdi/react';
|
|
import { mdiTagTextOutline, mdiAccountEdit, mdiLinkVariant } from '@mdi/js';
|
|
import MarkdownPreview from '@uiw/react-markdown-preview';
|
|
import {AuthorElement} from "./IAuthor";
|
|
import {LinkElement} from "./ILink";
|
|
import DownloadSingleChapterJob from "./Jobs/DownloadSingleChapterJob";
|
|
import IChapter from "./IChapter";
|
|
import Chapter from "../Chapter";
|
|
|
|
export default interface IManga{
|
|
mangaId: string;
|
|
connectorId: string;
|
|
name: string;
|
|
description: string;
|
|
websiteUrl: string;
|
|
year: number;
|
|
originalLanguage: string;
|
|
releaseStatus: MangaReleaseStatus;
|
|
folderName: string;
|
|
ignoreChapterBefore: number;
|
|
mangaConnectorId: string;
|
|
authorIds: string[];
|
|
tags: string[];
|
|
linkIds: string[];
|
|
altTitleIds: string[];
|
|
}
|
|
|
|
export enum MangaReleaseStatus {
|
|
Continuing = "Continuing",
|
|
Completed = "Completed",
|
|
OnHiatus = "OnHiatus",
|
|
Cancelled = "Cancelled",
|
|
Unreleased = "Unreleased",
|
|
}
|
|
|
|
export const defaultManga: IManga = {
|
|
altTitleIds: [],
|
|
authorIds: [],
|
|
connectorId: "",
|
|
description: "",
|
|
folderName: "",
|
|
ignoreChapterBefore: 0,
|
|
linkIds: [],
|
|
mangaConnectorId: "",
|
|
name: "",
|
|
originalLanguage: "",
|
|
releaseStatus: MangaReleaseStatus.Unreleased,
|
|
tags: [],
|
|
websiteUrl: "",
|
|
year: 0,
|
|
mangaId: ""
|
|
}
|
|
|
|
export function CoverCard({apiUri, mangaId} : {apiUri: string, mangaId: string}) : ReactElement {
|
|
let [manga, setContent] = React.useState<IManga>(defaultManga);
|
|
let [extendedInfo, setExtendedInfo] = React.useState(false);
|
|
|
|
useEffect(() => {
|
|
Manga.GetMangaById(apiUri, mangaId).then(setContent);
|
|
}, []);
|
|
|
|
const MangaCover : ReactEventHandler<HTMLImageElement> = (e) => {
|
|
if(e.currentTarget.src != Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget))
|
|
e.currentTarget.src = Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget);
|
|
}
|
|
|
|
return (
|
|
<div className="Manga" key={manga.mangaId} onClick={(e) => {
|
|
setExtendedInfo(!extendedInfo);
|
|
}}>
|
|
<img src={Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, undefined)} alt="Manga Cover" onLoad={MangaCover} onResize={MangaCover}></img>
|
|
<div className="SimpleCover">
|
|
<p className="pill connector-name">{manga.mangaConnectorId}</p>
|
|
<div className="Manga-status" release-status={manga.releaseStatus}></div>
|
|
<p className="Manga-name">{manga.name}</p>
|
|
</div>
|
|
{extendedInfo ? <div extended-info={extendedInfo ? "yes" : "no"}>
|
|
<ExtendedInfo apiUri={apiUri} manga={manga} actions={[
|
|
<button className="Manga-DeleteButton" onClick={() => {
|
|
Manga.DeleteManga(apiUri, manga.mangaId);
|
|
}}>Delete</button>
|
|
]} />
|
|
</div> : null}
|
|
</div>);
|
|
}
|
|
|
|
export function ExtendedInfo({apiUri, manga, actions} : {apiUri: string, manga: IManga, actions: ReactElement[]}) : ReactElement {
|
|
const MangaCover : ReactEventHandler<HTMLImageElement> = (e) => {
|
|
if(e.currentTarget.src != Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget))
|
|
e.currentTarget.src = Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget);
|
|
}
|
|
|
|
return(
|
|
<div className="SearchResult" key={manga.mangaId}>
|
|
<img src={Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, undefined)} alt="Manga Cover" onLoad={MangaCover} onResize={MangaCover}></img>
|
|
<p className="connector-name">{manga.mangaConnectorId}</p>
|
|
<div className="Manga-status" release-status={manga.releaseStatus}></div>
|
|
<p className="Manga-name"><a href={manga.websiteUrl}>{manga.name}<img src="../../media/link.svg"
|
|
alt=""/></a></p>
|
|
<div className="Manga-tags">
|
|
{manga.authorIds.map(authorId =>
|
|
<p className="Manga-author" key={manga.mangaId + "-author-" + authorId} >
|
|
<Icon path={mdiAccountEdit} size={0.5} />
|
|
<AuthorElement apiUri={apiUri} authorId={authorId}></AuthorElement>
|
|
</p>)}
|
|
{manga.tags.map(tag =>
|
|
<p className="Manga-tag" key={manga.mangaId + "-tag-" + tag}>
|
|
<Icon path={mdiTagTextOutline} size={0.5}/>
|
|
{tag}
|
|
</p>)}
|
|
{manga.linkIds.map(linkId =>
|
|
<p className="Manga-link" key={manga.mangaId + "-link-" + linkId}>
|
|
<Icon path={mdiLinkVariant} size={0.5}/>
|
|
<LinkElement apiUri={apiUri} linkId={linkId}></LinkElement>
|
|
</p>)}
|
|
</div>
|
|
<MarkdownPreview className="Manga-description" source={manga.description}
|
|
style={{backgroundColor: "transparent", color: "black"}}/>
|
|
<div className="Manga-actions">
|
|
{actions.map((p, i) => <div key={i}>{p}</div>)}
|
|
</div>
|
|
</div>);
|
|
}
|
|
|
|
export function ItemDownloadSingleChapterJob({apiUri, job} : {apiUri: string, job: DownloadSingleChapterJob}){
|
|
const MangaCover : ReactEventHandler<HTMLImageElement> = (e) => {
|
|
if(manga === null)
|
|
return;
|
|
if(e.currentTarget.src != Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget))
|
|
e.currentTarget.src = Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, e.currentTarget);
|
|
}
|
|
|
|
let [chapter, setChapter] = React.useState<IChapter|null>(null);
|
|
let [manga, setManga] = React.useState<IManga|null>(null);
|
|
|
|
useEffect(() => {
|
|
Chapter.GetChapterFromId(apiUri, job.chapterId).then(setChapter);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if(chapter === null){
|
|
setManga(null);
|
|
return;
|
|
}
|
|
Manga.GetMangaById(apiUri, chapter.parentMangaId).then(setManga);
|
|
}, [chapter]);
|
|
|
|
return (
|
|
<div className="DownloadSingleChapterJob" key={"DownloadSingleChapterJob-" + job.jobId}>
|
|
<img src={manga ? Manga.GetMangaCoverImageUrl(apiUri, manga.mangaId, undefined) : ""} alt="Manga Cover" onLoad={MangaCover} onResize={MangaCover}></img>
|
|
<p className="DownloadSingleChapterJob-Name">{manga ? manga.name : job.chapterId}</p>
|
|
<p className="DownloadSingleChapterJob-Title">
|
|
{chapter ? "Vol." + chapter.volumeNumber + " Ch." + chapter.chapterNumber + ": " + chapter.title : "loading"}
|
|
<a href={chapter ? chapter.url : ""}>
|
|
<img src="../../media/link.svg" alt=""/>
|
|
</a>
|
|
</p>
|
|
</div>
|
|
);
|
|
} |