mirror of
https://github.com/danbulant/Mangades
synced 2026-07-06 19:40:54 +00:00
improved more information page
This commit is contained in:
parent
c3e0dbe394
commit
9386952cd4
4 changed files with 177 additions and 42 deletions
|
|
@ -7,7 +7,7 @@ export async function load({ params }) {
|
||||||
if (blocked.includes(params.manga)) {
|
if (blocked.includes(params.manga)) {
|
||||||
throw error(404, 'blocked because of copyright');
|
throw error(404, 'blocked because of copyright');
|
||||||
}
|
}
|
||||||
const manga = await request("manga/" + params.manga + "?includes[]=author&includes[]=cover_art&includes[]=artist");
|
const manga = await request("manga/" + params.manga + "?includes[]=author&includes[]=cover_art&includes[]=artist&includes[]=manga");
|
||||||
console.log(manga);
|
console.log(manga);
|
||||||
return {
|
return {
|
||||||
manga: manga.data.attributes,
|
manga: manga.data.attributes,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
import Navbar from "./navbar.svelte";
|
import Navbar from "./navbar.svelte";
|
||||||
import ExpandableDescription from "./expandableDescription.svelte";
|
import ExpandableDescription from "./expandableDescription.svelte";
|
||||||
import { tick } from "svelte";
|
import { tick } from "svelte";
|
||||||
|
import Favicon from "./favicon.svelte";
|
||||||
|
import RelatedManga from "./relatedManga.svelte";
|
||||||
|
|
||||||
export var data;
|
export var data;
|
||||||
|
|
||||||
|
|
@ -294,23 +296,12 @@
|
||||||
|
|
||||||
var selectedImage = null;
|
var selectedImage = null;
|
||||||
|
|
||||||
const relatedMangaMap = {
|
|
||||||
spin_off: "Spin off",
|
|
||||||
doujinshi: "Doujinshi",
|
|
||||||
side_story: "Side story",
|
|
||||||
colored: "Colored version",
|
|
||||||
monochrome: "Monochrome version",
|
|
||||||
adapted_from: "Adapted from",
|
|
||||||
based_on: "Based on",
|
|
||||||
shared_universe: "Shared universe"
|
|
||||||
};
|
|
||||||
|
|
||||||
var width;
|
var width;
|
||||||
|
|
||||||
var smallScreenMode = width < 700;
|
var smallScreenMode = width < 700;
|
||||||
$: smallScreenMode = width < 700;
|
$: smallScreenMode = width < 700;
|
||||||
|
|
||||||
var scrollY, innerHeight, offsetHeight;
|
var scrollY, innerHeight;
|
||||||
|
|
||||||
let additionalImages = [];
|
let additionalImages = [];
|
||||||
|
|
||||||
|
|
@ -495,73 +486,77 @@
|
||||||
</SwiperSlide>
|
</SwiperSlide>
|
||||||
<SwiperSlide>
|
<SwiperSlide>
|
||||||
<div style="min-height: 30rem;">
|
<div style="min-height: 30rem;">
|
||||||
{#if anilistData} {#await anilistData then data}
|
|
||||||
Genres: {data.genres.join(", ")}
|
|
||||||
<br>
|
|
||||||
|
|
||||||
AL popularity: {data.popularity} <br>
|
|
||||||
favorite on AL: {data.isFavourite ? "yes" : "no"} <br>
|
|
||||||
AL score: {data.averageScore} <br>
|
|
||||||
Also known as: {data.synonyms.join(", ")} {Object.values(manga.title).filter(t => t !== title).join(", ")}
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
{/await} {/if}
|
|
||||||
|
|
||||||
<div class="flex-wrapped">
|
<div class="flex-wrapped">
|
||||||
{#if relationships.filter(t => t.type === "manga").length}
|
{#if anilistData} {#await anilistData then data}
|
||||||
<div>
|
<div>
|
||||||
<h4>Related manga</h4>
|
<b>Genres</b>: {data.genres.join(", ")}
|
||||||
{#each relationships.filter(t => t.type === "manga") as relatedManga}
|
<br>
|
||||||
<a href="/{relatedManga.id}">{relatedMangaMap[relatedManga.related] || relatedManga.related}</a> <br>
|
|
||||||
{/each}
|
<b>AL popularity</b>: {data.popularity} <br>
|
||||||
|
<b>favorite on AL</b>: {data.isFavourite ? "yes" : "no"} <br>
|
||||||
|
<b>AL score</b>: {data.averageScore} <br>
|
||||||
|
<b>Also known as</b>: {data.synonyms.join(", ")} {Object.values(manga.title).filter(t => t !== title).join(", ")}
|
||||||
|
|
||||||
|
<br><br>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/await} {/if}
|
||||||
{#if manga.links}
|
{#if manga.links}
|
||||||
<div>
|
<div>
|
||||||
<h4>Links</h4>
|
<h4>Links</h4>
|
||||||
|
|
||||||
{#if manga.links.al}
|
{#if manga.links.al}
|
||||||
<a href="https://anilist.co/manga/{manga.links.al}">Anilist</a> <br>
|
<a href="https://anilist.co/manga/{manga.links.al}"><Favicon url="https://anilist.co" /> Anilist</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.ap}
|
{#if manga.links.ap}
|
||||||
<a href="https://www.anime-planet.com/manga/{manga.links.ap}">Animeplanet</a> <br>
|
<a href="https://www.anime-planet.com/manga/{manga.links.ap}"><Favicon url="https://anime-planet.com" /> Animeplanet</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.bw}
|
{#if manga.links.bw}
|
||||||
<a href="https://bookwalker.jp/{manga.links.bw}">Bookwalker</a> <br>
|
<a href="https://bookwalker.jp/{manga.links.bw}"><Favicon url="https://bookwalker.jp" /> Bookwalker</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.mu}
|
{#if manga.links.mu}
|
||||||
<a href="https://www.mangaupdates.com/series.html?id={manga.links.mu}">Manga updates</a> <br>
|
<a href="https://www.mangaupdates.com/series.html?id={manga.links.mu}"><Favicon url="https://www.mangaupdates.com" /> Manga updates</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.nu}
|
{#if manga.links.nu}
|
||||||
<a href="https://www.novelupdates.com/series/{manga.links.nu}">Novel updates</a> <br>
|
<a href="https://www.novelupdates.com/series/{manga.links.nu}"><Favicon url="https://www.novelupdates.com" /> Novel updates</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.amz}
|
{#if manga.links.amz}
|
||||||
<a href={manga.links.amz}>Amazon</a> <br>
|
<a href={manga.links.amz}><Favicon url={manga.links.amz} /> Amazon</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.ebj}
|
{#if manga.links.ebj}
|
||||||
<a href={manga.links.ebj}>Ebookjapan</a> <br>
|
<a href={manga.links.ebj}><Favicon url={manga.links.ebj} /> Ebookjapan</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.mal}
|
{#if manga.links.mal}
|
||||||
<a href="https://myanimelist.net/manga/{manga.links.mal}">MyAnimeList</a> <br>
|
<a href="https://myanimelist.net/manga/{manga.links.mal}"><Favicon url="https://myanimelist.net" /> MyAnimeList</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.cdj}
|
{#if manga.links.cdj}
|
||||||
<a href="{manga.links.cdj}">CDJapan</a> <br>
|
<a href="{manga.links.cdj}"><Favicon url={manga.links.cdj} /> CDJapan</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.raw}
|
{#if manga.links.raw}
|
||||||
<a href="{manga.links.raw}">RAW</a> <br>
|
<a href="{manga.links.raw}"><Favicon url={manga.links.raw} /> RAW</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
{#if manga.links.engtl}
|
{#if manga.links.engtl}
|
||||||
<a href="{manga.links.engtl}">engtl</a> <br>
|
<a href="{manga.links.engtl}"><Favicon url={manga.links.engtl} /> engtl</a> <br>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<a href="https://mangadex.org/title/{mangaId}"><Favicon url="https://mangadex.org"/> Mangadex.org</a>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if relationships.filter(t => t.type === "manga").length}
|
||||||
|
<div>
|
||||||
|
<RelatedManga on:slideToClosest={() => swiper.slideToClosest()} mangaRelations={relationships.filter(t => t.type === "manga")} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</SwiperSlide>
|
</SwiperSlide>
|
||||||
</Swiper>
|
</Swiper>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
.tags {
|
.tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
||||||
11
src/routes/[manga]/favicon.svelte
Normal file
11
src/routes/[manga]/favicon.svelte
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { imageproxy } from "$lib/util/request";
|
||||||
|
|
||||||
|
export var url: string;
|
||||||
|
|
||||||
|
var domain = (new URL(url)).hostname;
|
||||||
|
$: domain = (new URL(url)).hostname;
|
||||||
|
$: favicon = `https://www.google.com/s2/favicons?domain=${domain}`;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<img src="{imageproxy}{favicon}" alt="">
|
||||||
129
src/routes/[manga]/relatedManga.svelte
Normal file
129
src/routes/[manga]/relatedManga.svelte
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import Item from "$lib/components/item.svelte";
|
||||||
|
import ShowTypeChooser, { showType } from "$lib/components/showTypeChooser.svelte";
|
||||||
|
import request, { imageproxy } from "$lib/util/request";
|
||||||
|
import { createEventDispatcher, tick } from "svelte";
|
||||||
|
|
||||||
|
const relatedMangaMap = {
|
||||||
|
main_story: "Main story",
|
||||||
|
prequel: "Prequel",
|
||||||
|
same_franchise: "Same franchise",
|
||||||
|
sequel: "Sequel",
|
||||||
|
alternate_story: "Alternate story",
|
||||||
|
alternate_version: "Alternate version",
|
||||||
|
preserialization: "Preserialization",
|
||||||
|
serialization: "Serialization",
|
||||||
|
spin_off: "Spin off",
|
||||||
|
doujinshi: "Doujinshi",
|
||||||
|
side_story: "Side story",
|
||||||
|
colored: "Colored version",
|
||||||
|
monochrome: "Monochrome version",
|
||||||
|
adapted_from: "Adapted from",
|
||||||
|
based_on: "Based on",
|
||||||
|
shared_universe: "Shared universe",
|
||||||
|
};
|
||||||
|
|
||||||
|
export var mangaRelations: {
|
||||||
|
id: string;
|
||||||
|
related: keyof typeof relatedMangaMap;
|
||||||
|
type: "manga";
|
||||||
|
attributes: {
|
||||||
|
title: {
|
||||||
|
en?: string;
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
availableTranslatedLanguages: string[];
|
||||||
|
contentRating: "safe" | "suggestive" | "erotica" | "pornographic";
|
||||||
|
description: {
|
||||||
|
en?: string;
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
status: string;
|
||||||
|
tags: {
|
||||||
|
id: string;
|
||||||
|
type: "tag";
|
||||||
|
attributes: {
|
||||||
|
name: {
|
||||||
|
en?: string;
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
group: string;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
year: number;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
|
||||||
|
let relations;
|
||||||
|
relations = getRelations(mangaRelations);
|
||||||
|
async function getRelations(rels) {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
for (let rel of rels) params.append("ids[]", rel.id);
|
||||||
|
params.append("limit", rels.length);
|
||||||
|
params.append("contentRating[]", "safe");
|
||||||
|
params.append("contentRating[]", "suggestive");
|
||||||
|
params.append("contentRating[]", "erotica");
|
||||||
|
params.append("contentRating[]", "pornographic");
|
||||||
|
params.append("includes[]", "cover_art");
|
||||||
|
const data = await request("manga?" + params);
|
||||||
|
console.log("rm", data.data);
|
||||||
|
return data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData(relation, relations) {
|
||||||
|
let res = relations.find((t) => t.id === relation.id);
|
||||||
|
console.log("gd", relation, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCoverArt(relation, relations) {
|
||||||
|
let data = getData(relation, relations);
|
||||||
|
return data.relationships.find((t) => t.type === "cover_art").attributes.fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
$: {
|
||||||
|
$showType;
|
||||||
|
setTimeout(() => dispatch("slideToClosest"), 100);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ShowTypeChooser />
|
||||||
|
|
||||||
|
<div class="grid" class:list={$showType == "list"}>
|
||||||
|
{#each mangaRelations as manga}
|
||||||
|
<a href="/manga/{manga.id}" class="manga">
|
||||||
|
{#await relations then relations}
|
||||||
|
<Item
|
||||||
|
r18={!['safe', 'suggestive'].includes(manga.attributes.contentRating)}
|
||||||
|
title={manga.attributes.title.en}
|
||||||
|
description={manga.attributes.description.en}
|
||||||
|
cover={`https://uploads.mangadex.org/covers/${manga.id}/${getCoverArt(manga, relations)}.512.jpg`}
|
||||||
|
|
||||||
|
/>
|
||||||
|
{/await}
|
||||||
|
</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, 11rem);
|
||||||
|
grid-gap: 1rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.grid.list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in a new issue