mirror of
https://github.com/danbulant/Mangades
synced 2026-06-17 21:31:03 +00:00
implement searc
This commit is contained in:
parent
21a71e1110
commit
6dd0906457
4 changed files with 200 additions and 20 deletions
|
|
@ -60,6 +60,9 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
}
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
.items {
|
||||
display: grid;
|
||||
93
src/components/mangadexItems.svelte
Normal file
93
src/components/mangadexItems.svelte
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<script>
|
||||
import SvelteMarkdown from "svelte-markdown";
|
||||
export var entries;
|
||||
export var itemsList;
|
||||
|
||||
$: console.log(entries);
|
||||
|
||||
function open(entry) {}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="items" class:items-list={itemsList}>
|
||||
{#each entries as entry}
|
||||
<a href="/{entry.id}" class="item" class:r18={!["safe", "ecchi"].includes(entry.attributes.contentRating)} on:click={() => open(entry)}>
|
||||
<div class="flex">
|
||||
{#if entry.relationships.find(t => t.type === "cover_art")}
|
||||
<img class="cover" draggable="false" src="https://cors-anywhere.danbulant.workers.dev/?https://uploads.mangadex.org/covers/{entry.id}/{entry.relationships.find(t => t.type === "cover_art").attributes.fileName}.512.jpg" alt="" on:click={() => selectedImage = `https://cors-anywhere.danbulant.workers.dev/?https://uploads.mangadex.org/covers/${mangaId}/${relationships.find(t => t.type === "cover_art").attributes.fileName}.512.jpg`}>
|
||||
{:else}
|
||||
Broken art
|
||||
{/if}
|
||||
<div class="info">
|
||||
<h3>{entry.attributes.title.en || entry.attributes.title.ja || Object.values(entry.attributes.title)[0]}</h3>
|
||||
{#if entry.attributes.lastChapter}
|
||||
<span>CH {entry.attributes.lastChapter}</span>
|
||||
{/if}
|
||||
{#if entry.attributes.lastVolume}
|
||||
<span>vol {entry.attributes.lastVolume}</span>
|
||||
{/if}
|
||||
{#if entry.attributes.description.en}
|
||||
<p><SvelteMarkdown source={entry.attributes.description.en} isInline /></p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
a {
|
||||
color: black;
|
||||
}
|
||||
a:hover {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
.items {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
||||
}
|
||||
.items-list.items {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.items-list .item img {
|
||||
height: 10rem;
|
||||
}
|
||||
.r18 img {
|
||||
filter: blur(10px);
|
||||
}
|
||||
.info {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transition: .2s opacity;
|
||||
}
|
||||
.items-list .info {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
.item img {
|
||||
border-radius: 5px;
|
||||
height: 15rem;
|
||||
width: auto;
|
||||
box-shadow: 0 0 0 white;
|
||||
transition: .4s box-shadow, .3s height;
|
||||
}
|
||||
@media(prefers-reduced-motion) {
|
||||
.item img, .item:hover img {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
.item:hover img {
|
||||
box-shadow: 0 0 10px grey;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
import { slide } from "svelte/transition";
|
||||
import { Swiper, SwiperSlide } from 'swiper/svelte';
|
||||
import ArtList from "../../components/artList.svelte";
|
||||
import SvelteMarkdown from 'svelte-markdown'
|
||||
import ArtDialog from "../../components/artDialog.svelte";
|
||||
import SvelteMarkdown from 'svelte-markdown';
|
||||
import ArtDialog from "../../components/artDialog.svelte";
|
||||
|
||||
export var scoped;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,84 @@
|
|||
<script>
|
||||
import { params } from '@roxi/routify';
|
||||
import request from "../util/request";
|
||||
import { goto } from '@roxi/routify/runtime/helpers';
|
||||
import { getUserDetails, getUserManga, isLogedIn } from "../util/anilist";
|
||||
import Items from "../components/items.svelte";
|
||||
import AnilistItems from "../components/anilistItems.svelte";
|
||||
import ListOrGrid from "../components/listOrGrid.svelte";
|
||||
import ratelimit from '../util/ratelimit';
|
||||
import MangadexItems from '../components/mangadexItems.svelte';
|
||||
|
||||
var name = "";
|
||||
var name = $params.search;
|
||||
$: {
|
||||
const url = new URL(window.location.toString());
|
||||
url.searchParams.set("search", name || "");
|
||||
history.replaceState(history.state, "", url.toString());
|
||||
}
|
||||
const filters = {
|
||||
contentRating: ["safe", "suggestive"],
|
||||
demographic: [],
|
||||
status: [],
|
||||
sort: "updatedAt",
|
||||
sortValue: "desc"
|
||||
};
|
||||
/**
|
||||
* Searches for results
|
||||
* @param {string} title
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
async function search(title, filters, offset=0) {
|
||||
var query = new URLSearchParams();
|
||||
if(title) query.set("title", title);
|
||||
query.set("limit", 100);
|
||||
query.set("offset", offset);
|
||||
query.append("includes[]", "author");
|
||||
query.append("includes[]", "cover_art");
|
||||
query.append("includes[]", "artist");
|
||||
for(const rating of filters.contentRating) {
|
||||
query.append("contentRating[]", rating);
|
||||
}
|
||||
for(const demographic of filters.demographic) {
|
||||
query.append("demographic[]", demographic);
|
||||
}
|
||||
for(const status of filters.status) {
|
||||
query.append("status[]", status);
|
||||
}
|
||||
query.set("order[" + filters.sort + "]", filters.sortValue);
|
||||
const res = await request("manga", query);
|
||||
for(const manga of res.data) {
|
||||
for(const relation of manga.relationships) {
|
||||
if(relation.type === "cover") {
|
||||
console.log(manga, relation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function update(name, filters) {
|
||||
if(!name) return result = null;
|
||||
result = ratelimit(search, name, filters);
|
||||
result.then(t => console.log(t));
|
||||
}
|
||||
var result;
|
||||
$: isLogedIn() && update(name, filters);
|
||||
var scrollSearch = null;
|
||||
/**
|
||||
* @param {MouseEvent} e
|
||||
*/
|
||||
async function scroll(e) {
|
||||
if(scrollSearch !== null) return;
|
||||
if(document.body.scrollHeight - window.scrollY - window.innerHeight < 300 && (await result).results.length < (await result).total) {
|
||||
scrollSearch = name;
|
||||
const res = await search(name, filters, (await result).results.length);
|
||||
if(scrollSearch === name && res.results.length) {
|
||||
(await result).results.push(...res.results);
|
||||
result = result; // trigger reload
|
||||
}
|
||||
setTimeout(() => {
|
||||
scrollSearch = null;
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
var randomMangaLoading = false;
|
||||
async function randomManga() {
|
||||
|
|
@ -32,6 +105,8 @@
|
|||
let listStyle = false;
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={scroll} />
|
||||
|
||||
<svelte:head>
|
||||
<title>Mangadex search & downloader</title>
|
||||
<meta name="description" value="Read manga from Mangadex online, or download it as EPUB or CBZ file to read it on your e-reader." />
|
||||
|
|
@ -63,30 +138,31 @@
|
|||
{#if isLogedIn()}
|
||||
<ListOrGrid bind:list={listStyle} />
|
||||
|
||||
<div>
|
||||
{#await userManga then userManga}
|
||||
{#each userManga.data.MediaListCollection.lists as list}
|
||||
<h2>{list.name}</h2>
|
||||
<Items entries={list.entries} itemsList={listStyle} />
|
||||
{/each}
|
||||
{#if result}
|
||||
<h2>Search results</h2>
|
||||
{#await result}
|
||||
Loading...
|
||||
{:then result}
|
||||
<MangadexItems entries={result.data} itemsList={listStyle} />
|
||||
{/await}
|
||||
</div>
|
||||
{:else}
|
||||
<div>
|
||||
{#await userManga then userManga}
|
||||
{#each userManga.data.MediaListCollection.lists as list}
|
||||
<h2>{list.name}</h2>
|
||||
<AnilistItems entries={list.entries} itemsList={listStyle} />
|
||||
{/each}
|
||||
{/await}
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<p>
|
||||
Sign in via Anilist to view your manga list.
|
||||
Sign in via Anilist to view your manga list and search for manga online.
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<hr>
|
||||
|
||||
<p>This site works by using Mangadex API <i>from your browser</i>, and loading or downloading the manga directly from MD@H, without using my servers (so I don't host any content seen here, nor can I delete it). The whole site is client side only (it runs in your browser). I cannot delete any content (images or text), only hide it from this specific site - but there are tons of other sites, and anybody with decent coding skills can clone this page and remove the rule hiding the content (this page is open source).</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<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. /s</i></p>
|
||||
|
||||
<hr>
|
||||
|
||||
<b>Shameless plug:</b>
|
||||
|
||||
<p>
|
||||
|
|
@ -98,6 +174,14 @@
|
|||
<p>
|
||||
Website's source code available on <b><a href="https://github.com/danbulant/mangades">GitHub</a></b> under GPLv3. Hosted on Cloudflare Pages, a static site hosting, where none of the images are stored.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>This site works by using Mangadex API <i>from your browser</i>, and loading or downloading the manga directly from MD@H, without using my servers (so I don't host any content seen here, nor can I delete it). The whole site is client side only (it runs in your browser). I cannot delete any content (images or text), only hide it from this specific site - but there are tons of other sites, and anybody with decent coding skills can clone this page and remove the rule hiding the content (this page is open source).</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<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. /s</i></p>
|
||||
</main>
|
||||
|
||||
<style lang="postcss">
|
||||
|
|
|
|||
Loading…
Reference in a new issue