mirror of
https://github.com/danbulant/Mangades
synced 2026-05-24 12:22:10 +00:00
some small tweaks
This commit is contained in:
parent
dce011fcd3
commit
173d53b261
16 changed files with 365 additions and 194 deletions
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
17
|
||||
24
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
# Mangades
|
||||
|
||||
Mangadex viewer and downloader. Uses svelte+routify.
|
||||
Mangadex viewer and downloader website, with read-only anilist integration.
|
||||
|
||||
Minimalistic.
|
||||
|
||||
|
||||
See it live [here at manga.danbulant.eu](https://manga.danbulant.eu).
|
||||
See it in action [here](https://manga.danbulant.eu).
|
||||
|
|
@ -34,5 +34,6 @@
|
|||
"svelte-local-storage-store": "^0.3.1",
|
||||
"svelte-markdown": "^0.2.3",
|
||||
"swiper": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@9.5.0+sha1.8c155dc114e1689d18937974f6571e0ceee66f1d"
|
||||
}
|
||||
|
|
|
|||
8
shell.nix
Normal file
8
shell.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs-slim
|
||||
corepack
|
||||
];
|
||||
}
|
||||
|
|
@ -1,23 +1,29 @@
|
|||
<script>
|
||||
import { goto } from "$app/navigation";
|
||||
import { goto, preloadData } from "$app/navigation";
|
||||
import { flip } from "svelte/animate";
|
||||
import { blur } from "svelte/transition";
|
||||
import request from "../util/request";
|
||||
import { blur, crossfade } from "svelte/transition";
|
||||
import request, { imageproxy } from "../util/request";
|
||||
import Item from "./item.svelte";
|
||||
import { showType } from "./showTypeChooser.svelte";
|
||||
import { quintOut } from "svelte/easing";
|
||||
import { sleep } from "$lib/util/ratelimit";
|
||||
import { logs } from "$lib/util/logs";
|
||||
|
||||
export var lists;
|
||||
|
||||
var isLoading = false;
|
||||
let isLoading = false;
|
||||
let selectedEntry;
|
||||
async function find(entry) {
|
||||
selectedEntry = entry;
|
||||
isLoading = true;
|
||||
if(typeof localStorage !== "undefined") {
|
||||
let cache = localStorage.getItem("anilist-mangadex-" + entry.media.id);
|
||||
if(cache) {
|
||||
goto("./" + cache);
|
||||
setTimeout(() => goto("./" + cache), 300);
|
||||
return;
|
||||
}
|
||||
}
|
||||
isLoading = true;
|
||||
let sleeping = sleep(350);
|
||||
var query = new URLSearchParams();
|
||||
query.set("title", entry.media.title.romaji);
|
||||
query.append("contentRating[]", "safe");
|
||||
|
|
@ -32,8 +38,12 @@
|
|||
result = await request("manga", query);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
isLoading = false;
|
||||
// $logs.push({ type: 'error', text: "Failed to search mangadex." });
|
||||
// $logs = $logs;
|
||||
// await sleeping;
|
||||
// isLoading = false;
|
||||
alert("Failed to search mangadex.");
|
||||
location.reload()
|
||||
return;
|
||||
}
|
||||
console.log("anilist mangadex data", result.data);
|
||||
|
|
@ -45,28 +55,76 @@
|
|||
if(!item) item = result.data.find(t => t.attributes.altTitles.find(t => Object.values(t).find(t => Object.values(entry.media.title).filter(t => t).map(t => t.toLowerCase()).includes(t.toLowerCase()))));
|
||||
console.log("anilist mangadex item", item);
|
||||
if(!item) {
|
||||
alert(`Couldn't find any mangadex entry.`);
|
||||
isLoading = false;
|
||||
// $logs.push({ type: 'error', text: `Couldn't find any mangadex entry.` });
|
||||
// $logs = $logs;
|
||||
// await sleeping;
|
||||
// isLoading = false;
|
||||
alert("Couldn't find any mangadex entry.");
|
||||
location.reload()
|
||||
return
|
||||
}
|
||||
if(typeof localStorage !== "undefined") {
|
||||
localStorage.setItem("anilist-mangadex-" + entry.media.id, item.id);
|
||||
}
|
||||
goto("./" + item.id);
|
||||
try {
|
||||
await preloadData('./' + item.id);
|
||||
await sleeping;
|
||||
await goto("./" + item.id);
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
alert("Failed to open, please try again later.");
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
$: console.log(selectedEntry)
|
||||
|
||||
const [send, receive] = crossfade({
|
||||
duration: 300,
|
||||
easing: quintOut
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if isLoading}
|
||||
<dialog open>
|
||||
Finding the manga
|
||||
</dialog>
|
||||
{/if}
|
||||
{#if selectedEntry.media.bannerImage}
|
||||
<div class="banner-container">
|
||||
<img class="banner" src={selectedEntry.media.bannerImage} alt="">
|
||||
<div class="fader"></div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="items" class:list={$showType == "list"}>
|
||||
<div class="infoflex">
|
||||
{#if selectedEntry.media.coverImage.large}
|
||||
<div class="cover-container" in:send={{ key: selectedEntry.media.id }}>
|
||||
<img class="cover" class:r18={selectedEntry.media.isAdult} draggable="false" src="{selectedEntry.media.coverImage.large}" alt="" >
|
||||
<img class="cover-backdrop" draggable="false" src="{selectedEntry.media.coverImage.large}" alt="">
|
||||
</div>
|
||||
{/if}
|
||||
<div class="info">
|
||||
<h1>{selectedEntry.media.title.userPreferred}</h1>
|
||||
|
||||
<h3>
|
||||
{#if selectedEntry.media.startDate?.year}
|
||||
{selectedEntry.media.startDate.year} ·
|
||||
{/if}
|
||||
{#if selectedEntry?.status} {selectedEntry.status} · {/if}
|
||||
{selectedEntry.media.isAdult ? 'adult' : 'safe/suggestive'}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="loading">
|
||||
Loading...
|
||||
</div>
|
||||
</dialog>
|
||||
{:else}
|
||||
<!-- This has to be in `if` to trigger the out transition -->
|
||||
<div class="items" class:list={$showType === "list"}>
|
||||
{#each lists as list}
|
||||
<h2>{list.name}</h2>
|
||||
{#each list.entries.sort((a, b) => a.priority - b.priority) as entry (entry.media.id)}
|
||||
<div class="h-full" animate:flip transition:blur>
|
||||
<div class="h-full" animate:flip in:blur out:receive={{ key: entry.media.id }}>
|
||||
<Item
|
||||
r18={entry.media.isAdult}
|
||||
cover={entry.media.coverImage.large}
|
||||
|
|
@ -75,13 +133,14 @@
|
|||
chapterProgress={entry.progress}
|
||||
score={entry.score || "?"}
|
||||
description={entry.notes}
|
||||
coverColor={entry.media.coverImage.color == "null" ? null : entry.media.coverImage.color}
|
||||
coverColor={entry.media.coverImage.color === "null" ? null : entry.media.coverImage.color}
|
||||
on:click={() => find(entry)}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
dialog {
|
||||
|
|
@ -93,6 +152,80 @@
|
|||
z-index: 100;
|
||||
background: black;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.infoflex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: calc(5rem + 15px) calc(1rem + 15px);
|
||||
justify-content: start;
|
||||
gap: 1rem;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
.cover.r18 {
|
||||
filter: blur(15px);
|
||||
transition: filter .3s;
|
||||
}
|
||||
.cover.r18:hover {
|
||||
filter: blur(0);
|
||||
}
|
||||
.banner-container {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
user-select: none;
|
||||
}
|
||||
.banner {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
overflow: hidden;
|
||||
}
|
||||
.banner-container .fader {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
background: linear-gradient(180deg, rgba(0,0,0,0.1) 0%, rgba(0,0,0,1) 100%);
|
||||
}
|
||||
|
||||
.cover-container {
|
||||
position: relative;
|
||||
height: 20rem;
|
||||
flex-shrink: 0;
|
||||
margin-right: 15px;
|
||||
transition: height .3s;
|
||||
}
|
||||
.cover {
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.cover-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: calc(100% + 4px);
|
||||
height: calc(100% + 4px);
|
||||
z-index: 0;
|
||||
filter: blur(18px) saturate(100%);
|
||||
transition: filter .3s;
|
||||
}
|
||||
.cover-container:hover .cover-backdrop {
|
||||
filter: blur(30px) saturate(150%);
|
||||
}
|
||||
h2 {
|
||||
grid-column: 1 / -1;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
<style>
|
||||
div {
|
||||
display: flex;
|
||||
margin: 0 1rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
button {
|
||||
border-radius: 0;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { apm } from "./tracing";
|
||||
// import { apm } from "./tracing";
|
||||
|
||||
var isLogedInCache: boolean | null = null;
|
||||
var isLogedInCacheTime: number | null = null;
|
||||
|
|
@ -21,7 +21,7 @@ export function isLogedIn() {
|
|||
export function getUserID() {
|
||||
const token = localStorage.getItem("token")!;
|
||||
let data = JSON.parse(atob(token.substring(token.indexOf(".") + 1, token.lastIndexOf("."))));
|
||||
apm.setUserContext({ id: data.sub });
|
||||
// apm.setUserContext({ id: data.sub });
|
||||
return data.sub;
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +104,10 @@ export function getUserManga() {
|
|||
status
|
||||
chapters
|
||||
volumes
|
||||
startDate {
|
||||
year
|
||||
}
|
||||
bannerImage
|
||||
coverImage {
|
||||
large
|
||||
medium
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
export const logs = writable([]);
|
||||
3
src/lib/util/logs.ts
Normal file
3
src/lib/util/logs.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
export const logs = writable<{ type: string, text: string }[]>([]);
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
const ratelimits = new Map();
|
||||
|
||||
export function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function callback({ func }) {
|
||||
const params = ratelimits.get(func);
|
||||
console.log("ratelimit", params, func, ratelimits);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { ApmBase, init as initApm } from '@elastic/apm-rum'
|
||||
// import { browser } from '$app/environment';
|
||||
// import { ApmBase, init as initApm } from '@elastic/apm-rum'
|
||||
|
||||
var apm_: ApmBase;
|
||||
|
||||
if(browser) {
|
||||
apm_ = initApm({
|
||||
// Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)
|
||||
serviceName: 'mangades',
|
||||
|
||||
// Set custom APM Server URL (default: http://localhost:8200)
|
||||
serverUrl: 'https://apm.elasticsearch.danbulant.cloud',
|
||||
|
||||
// Set the service version (required for source map feature)
|
||||
// serviceVersion: import.meta.env.VITE_SENTRY_RELEASE,
|
||||
|
||||
// Set the service environment
|
||||
environment: import.meta.env.VITE_SENTRY_ENVIRONMENT || 'production'
|
||||
});
|
||||
}
|
||||
|
||||
export const apm = apm_;
|
||||
// var apm_: ApmBase;
|
||||
//
|
||||
// if(browser) {
|
||||
// apm_ = initApm({
|
||||
// // Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)
|
||||
// serviceName: 'mangades',
|
||||
//
|
||||
// // Set custom APM Server URL (default: http://localhost:8200)
|
||||
// serverUrl: 'https://apm.elasticsearch.danbulant.cloud',
|
||||
//
|
||||
// // Set the service version (required for source map feature)
|
||||
// // serviceVersion: import.meta.env.VITE_SENTRY_RELEASE,
|
||||
//
|
||||
// // Set the service environment
|
||||
// environment: import.meta.env.VITE_SENTRY_ENVIRONMENT || 'production'
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// export const apm = apm_;
|
||||
|
|
@ -2,14 +2,8 @@
|
|||
import { afterNavigate } from "$app/navigation";
|
||||
import { logs } from "$lib/util/logs";
|
||||
import PageTransition from "./pageTransition.svelte";
|
||||
import { browser } from '$app/environment';
|
||||
import { apm } from "$lib/util/tracing";
|
||||
import { page } from "$app/stores";
|
||||
|
||||
export var data;
|
||||
if(browser) {
|
||||
apm.setInitialPageLoadName($page.route.id);
|
||||
}
|
||||
|
||||
let last = typeof window !== "undefined" && window.location.pathname;
|
||||
afterNavigate(page => {
|
||||
|
|
@ -39,10 +33,23 @@
|
|||
} else {
|
||||
document.body.classList.remove("dark");
|
||||
}
|
||||
|
||||
let inc = 0;
|
||||
let lastUrl = data.url;
|
||||
function increase() {
|
||||
if(lastUrl == data.url) return;
|
||||
let pagesToTransitionTo = ['/', '/about', '/callback', '/random']
|
||||
if(pagesToTransitionTo.includes(data.url) || pagesToTransitionTo.find(t => data.url.startsWith(t + '?'))) {
|
||||
inc++
|
||||
}
|
||||
lastUrl = data.url;
|
||||
}
|
||||
|
||||
$: increase(data.url)
|
||||
</script>
|
||||
|
||||
<div class:dark={darkmode} class="main">
|
||||
<PageTransition url={data.url}>
|
||||
<PageTransition {inc}>
|
||||
<slot />
|
||||
</PageTransition>
|
||||
</div>
|
||||
|
|
@ -91,7 +98,8 @@
|
|||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
background: black;
|
||||
color: white;
|
||||
border-radius: 5px 0 0 0;
|
||||
padding: 5px;
|
||||
box-shadow: 0 0 2px 0 black;
|
||||
|
|
|
|||
|
|
@ -6,16 +6,20 @@
|
|||
import ratelimit from '$lib/util/ratelimit';
|
||||
import MangadexItems from '$lib/components/mangadexItems.svelte';
|
||||
import { goto } from "$app/navigation";
|
||||
|
||||
import type { load } from "./+page";
|
||||
import Navbar from "$lib/components/navbar.svelte";
|
||||
import ShowNsfwChooser, { showNsfw } from "$lib/components/showNsfwChooser.svelte";
|
||||
|
||||
import type { load } from "./+page";
|
||||
export var data: Awaited<ReturnType<typeof load>>;
|
||||
|
||||
var name: string = typeof window === "undefined" ? "" : data.url.searchParams.get("search") || "";
|
||||
$: if(typeof window !== "undefined") {
|
||||
const url = new URL(window.location.toString());
|
||||
if(name) {
|
||||
url.searchParams.set("search", name || "");
|
||||
} else {
|
||||
url.searchParams.delete("search");
|
||||
}
|
||||
history.replaceState(history.state, "", url.toString());
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +135,7 @@
|
|||
<div class="nsfw">
|
||||
<ShowNsfwChooser />
|
||||
</div>
|
||||
<a href="https://discord.gg/XKPbz5xRuK">Made by TechmandanCZ#3372</a>
|
||||
<span>Made by <a href="https://discord.gg/XKPbz5xRuK">techmandancz</a></span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/random" class="button" style="width: 100%; margin-bottom: 0.4rem; display: inline-block;">Random</a>
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@
|
|||
var smallScreenMode = width < 700;
|
||||
$: smallScreenMode = width < 700;
|
||||
|
||||
var scrollY, innerHeight;
|
||||
var scrollY = 0, innerHeight = 1;
|
||||
|
||||
let additionalImages = [];
|
||||
let alReadProgress
|
||||
|
|
@ -363,16 +363,18 @@
|
|||
{/if}
|
||||
</ArtDialog>
|
||||
|
||||
{#if anilistData} {#await anilistData then data}
|
||||
|
||||
<main class:smallScreenMode>
|
||||
<div class="header">
|
||||
{#if anilistData} {#await anilistData then data}
|
||||
{#if data && data.bannerImage}
|
||||
<div class="banner-container">
|
||||
<img class="banner" src={data.bannerImage} on:click={() => selectedImage = data.bannerImage} alt="">
|
||||
<div class="fader"></div>
|
||||
</div>
|
||||
{/if}
|
||||
{/await} {/if}
|
||||
{/await} {/if}
|
||||
|
||||
<main class:smallScreenMode>
|
||||
<div class="flex infoflex">
|
||||
{#if relationships.find(t => t.type === "cover_art")}
|
||||
<div class="cover-container">
|
||||
|
|
@ -455,6 +457,7 @@
|
|||
{/if}
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<Tabs list={tabs} bind:selected={selectedTab} />
|
||||
|
||||
|
|
@ -546,40 +549,40 @@
|
|||
<h4>Links</h4>
|
||||
|
||||
{#if manga.links.al}
|
||||
<a href="https://anilist.co/manga/{manga.links.al}"><Favicon url="https://anilist.co" /> Anilist</a> <br>
|
||||
<a target="_blank" href="https://anilist.co/manga/{manga.links.al}"><Favicon url="https://anilist.co" /> Anilist</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.ap}
|
||||
<a href="https://www.anime-planet.com/manga/{manga.links.ap}"><Favicon url="https://anime-planet.com" /> Animeplanet</a> <br>
|
||||
<a target="_blank" href="https://www.anime-planet.com/manga/{manga.links.ap}"><Favicon url="https://anime-planet.com" /> Animeplanet</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.bw}
|
||||
<a href="https://bookwalker.jp/{manga.links.bw}"><Favicon url="https://bookwalker.jp" /> Bookwalker</a> <br>
|
||||
<a target="_blank" href="https://bookwalker.jp/{manga.links.bw}"><Favicon url="https://bookwalker.jp" /> Bookwalker</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.mu}
|
||||
<a href="https://www.mangaupdates.com/series.html?id={manga.links.mu}"><Favicon url="https://www.mangaupdates.com" /> Manga updates</a> <br>
|
||||
<a target="_blank" href="https://www.mangaupdates.com/series.html?id={manga.links.mu}"><Favicon url="https://www.mangaupdates.com" /> Manga updates</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.nu}
|
||||
<a href="https://www.novelupdates.com/series/{manga.links.nu}"><Favicon url="https://www.novelupdates.com" /> Novel updates</a> <br>
|
||||
<a target="_blank" href="https://www.novelupdates.com/series/{manga.links.nu}"><Favicon url="https://www.novelupdates.com" /> Novel updates</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.amz}
|
||||
<a href={manga.links.amz}><Favicon url={manga.links.amz} /> Amazon</a> <br>
|
||||
<a target="_blank" href={manga.links.amz}><Favicon url={manga.links.amz} /> Amazon</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.ebj}
|
||||
<a href={manga.links.ebj}><Favicon url={manga.links.ebj} /> Ebookjapan</a> <br>
|
||||
<a target="_blank" href={manga.links.ebj}><Favicon url={manga.links.ebj} /> Ebookjapan</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.mal}
|
||||
<a href="https://myanimelist.net/manga/{manga.links.mal}"><Favicon url="https://myanimelist.net" /> MyAnimeList</a> <br>
|
||||
<a target="_blank" href="https://myanimelist.net/manga/{manga.links.mal}"><Favicon url="https://myanimelist.net" /> MyAnimeList</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.cdj}
|
||||
<a href="{manga.links.cdj}"><Favicon url={manga.links.cdj} /> CDJapan</a> <br>
|
||||
<a target="_blank" href="{manga.links.cdj}"><Favicon url={manga.links.cdj} /> CDJapan</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.raw}
|
||||
<a href="{manga.links.raw}"><Favicon url={manga.links.raw} /> RAW</a> <br>
|
||||
<a target="_blank" href="{manga.links.raw}"><Favicon url={manga.links.raw} /> RAW</a> <br>
|
||||
{/if}
|
||||
{#if manga.links.engtl}
|
||||
<a href="{manga.links.engtl}"><Favicon url={manga.links.engtl} /> engtl</a> <br>
|
||||
<a target="_blank" href="{manga.links.engtl}"><Favicon url={manga.links.engtl} /> engtl</a> <br>
|
||||
{/if}
|
||||
|
||||
<a href="https://mangadex.org/title/{mangaId}"><Favicon url="https://mangadex.org"/> Mangadex.org</a>
|
||||
<a target="_blank" href="https://mangadex.org/title/{mangaId}"><Favicon url="https://mangadex.org"/> Mangadex.org</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -613,17 +616,22 @@
|
|||
</main>
|
||||
|
||||
<style>
|
||||
.header {
|
||||
position: relative;
|
||||
padding-top: 5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
.art-list {
|
||||
margin-top: 2rem;
|
||||
margin: 1rem 2rem 1rem 1rem;
|
||||
}
|
||||
.chapter-list {
|
||||
margin-top: 1rem;
|
||||
margin: 1rem;
|
||||
}
|
||||
.more-info {
|
||||
margin-top: 2rem;
|
||||
margin: 1rem 2rem 1rem 1rem;
|
||||
}
|
||||
.characters {
|
||||
margin-top: 1rem;
|
||||
margin: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
grid-gap: 2rem;
|
||||
|
|
@ -669,6 +677,9 @@
|
|||
.tags {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
margin: 0 1rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.tags.expanded {
|
||||
flex-wrap: wrap;
|
||||
|
|
@ -688,6 +699,8 @@
|
|||
margin: 15px;
|
||||
justify-content: start;
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.flex-wrapped {
|
||||
display: flex;
|
||||
|
|
@ -705,15 +718,17 @@
|
|||
filter: blur(0);
|
||||
}
|
||||
.banner-container {
|
||||
margin-top: -5rem;
|
||||
width: 100%;
|
||||
max-height: 40vh;
|
||||
max-height: 100%;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
user-select: none;
|
||||
}
|
||||
.banner {
|
||||
width: 100%;
|
||||
max-height: 40vh;
|
||||
max-height: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
overflow: hidden;
|
||||
|
|
@ -772,9 +787,6 @@
|
|||
.block {
|
||||
display: block;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding-top: 0.5rem;
|
||||
|
|
@ -835,11 +847,10 @@
|
|||
}
|
||||
main {
|
||||
font-size: 1.1rem;
|
||||
padding-bottom: 1rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
/* background: linear-gradient(to bottom, rgba(0,0,0,0.3) 0vh, rgba(0,0,0,1) 30vh); */
|
||||
padding-top: 5rem;
|
||||
|
||||
padding: 0 0 1rem 0;
|
||||
}
|
||||
.no-wrap {
|
||||
white-space: nowrap;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<Navbar title="About" />
|
||||
|
||||
<main style="padding-top: 6rem;">
|
||||
<a href="https://discord.gg/XKPbz5xRuK">Made by TechmandanCZ#3372</a>
|
||||
Made by <a href="https://discord.gg/XKPbz5xRuK">techmandancz</a>
|
||||
|
||||
<hr>
|
||||
|
||||
|
|
@ -34,6 +34,4 @@
|
|||
<p>DISCLAIMER: This site isn't distributing any content and is using mangadex.org API. All of the site's requests are done client side, my servers aren't sharing any manga data. Website is open source, and I don't claim any copyright on the publications. <i>If you believe in good faith you're downloading copyrighted content, file a DMCA at yourself, your operating system (as it took a part in the download), your ISP, your browser and all the free libraries that are used in any of the previous (made by volunteers), and then here. /satire</i></p>
|
||||
|
||||
<p>For DMCA requests, I recommend going to the mangadex page of the selected manga instead and reporting it there, as it will be taken down more quickly. You can of course report it to me and I'll block the page from viewing it, but it's trivial to remove that (1 required software installed to run this site, edit single line, run 2 more commands and you have bypassed the block), so I really recommend removing the source instead.</p>
|
||||
|
||||
<a href="/error">Crash</a>
|
||||
</main>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import { fade } from "svelte/transition";
|
||||
export let url = "";
|
||||
export let inc;
|
||||
</script>
|
||||
|
||||
{#key url}
|
||||
{#key inc}
|
||||
<div
|
||||
in:fade={{ opacity: 1, duration: 200, delay: 150 }}
|
||||
out:fade={{ opacity: 0, duration: 200 }}
|
||||
|
|
|
|||
Loading…
Reference in a new issue