mirror of
https://github.com/danbulant/Mangades
synced 2026-06-18 05:41:05 +00:00
various small improvements
This commit is contained in:
parent
30cb06bd0b
commit
44b3e042bb
8 changed files with 77 additions and 34 deletions
|
|
@ -20,6 +20,7 @@ main
|
|||
{
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
|
|||
22
package.json
22
package.json
|
|
@ -26,15 +26,15 @@
|
|||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^19.0.2",
|
||||
"@rollup/plugin-node-resolve": "13.0.0",
|
||||
"@roxi/routify": "^2.18.4",
|
||||
"@roxi/routify": "^2.18.8",
|
||||
"@types/streamsaver": "^2.0.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"nollup": "^0.16.5",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.5",
|
||||
"postcss-import": "^14.0.2",
|
||||
"rollup": "^2.63.0",
|
||||
"postcss": "^8.4.16",
|
||||
"postcss-import": "^14.1.0",
|
||||
"rollup": "^2.79.0",
|
||||
"rollup-plugin-hot": "^0.1.1",
|
||||
"rollup-plugin-livereload": "^2.0.5",
|
||||
"rollup-plugin-svelte": "^7.1.0",
|
||||
|
|
@ -43,8 +43,8 @@
|
|||
"rollup-plugin-workbox": "^5.2.1",
|
||||
"spank": "^1.9.0",
|
||||
"spassr": "^2.6.0",
|
||||
"svelte": "^3.45.0",
|
||||
"svelte-preprocess": "^4.10.1",
|
||||
"svelte": "^3.50.0",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tossr": "^1.4.2"
|
||||
},
|
||||
"routify": {
|
||||
|
|
@ -57,9 +57,11 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "1.0.0-beta.3",
|
||||
"fflate": "^0.6.10",
|
||||
"streamsaver": "^2.0.5",
|
||||
"svelte-markdown": "^0.2.2",
|
||||
"swiper": "^8.1.5"
|
||||
"streamsaver": "^2.0.6",
|
||||
"svelte-local-storage-store": "^0.3.1",
|
||||
"svelte-markdown": "^0.2.3",
|
||||
"swiper": "^8.3.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import request from "../util/request";
|
||||
import { goto } from '@roxi/routify/runtime/helpers';
|
||||
import autoAnimate from "@formkit/auto-animate";
|
||||
import request from "../util/request";
|
||||
|
||||
export var entries;
|
||||
export var itemsList;
|
||||
|
|
@ -12,7 +13,15 @@
|
|||
query.set("title", entry.media.title.romaji);
|
||||
query.set("limit", 20);
|
||||
console.log(entry);
|
||||
const result = await request("manga", query);
|
||||
let result;
|
||||
try {
|
||||
result = await request("manga", query);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
isLoading = false;
|
||||
alert("Failed to search mangadex.");
|
||||
return;
|
||||
}
|
||||
console.log(result.data);
|
||||
let item = result.data.find(t => t.attributes.links.al === entry.media.id.toString());
|
||||
if(!item) item = result.data.find(t => t.attributes.title.en?.toLowerCase() === entry.media.title.english.toLowerCase());
|
||||
|
|
@ -20,7 +29,7 @@
|
|||
if(!item) item = result.data.find(t => t.attributes.altTitles.find(t => Object.values(t).find(t => t.toLowerCase() === entry.media.title.native.toLowerCase())));
|
||||
console.log(item);
|
||||
if(!item) {
|
||||
alert(`Couldn't find any mangadex entry`);
|
||||
alert(`Couldn't find any mangadex entry.`);
|
||||
isLoading = false;
|
||||
return
|
||||
}
|
||||
|
|
@ -34,11 +43,11 @@
|
|||
</dialog>
|
||||
{/if}
|
||||
|
||||
<div class="items" class:items-list={itemsList}>
|
||||
<div class="items" class:items-list={itemsList} use:autoAnimate>
|
||||
{#each entries.sort((a, b) => a.priority - b.priority) as entry}
|
||||
<div class="item" class:r18={entry.media.isAdult} on:click={() => find(entry)}>
|
||||
<div class="flex">
|
||||
<img src={entry.media.coverImage.large} width=100 height=142 alt="{entry.media.title.userPreferred}">
|
||||
<img src={entry.media.coverImage.large} width=100 height=142 alt="{entry.media.title.userPreferred}" title="{entry.media.title.userPreferred}">
|
||||
<div class="info">
|
||||
<h3>{entry.media.title.userPreferred}</h3>
|
||||
<span>[{entry.progress}/{entry.media.chapters || "?"}]</span> <br>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<script>
|
||||
import SvelteMarkdown from "svelte-markdown";
|
||||
import autoAnimate from "@formkit/auto-animate";
|
||||
|
||||
export var entries;
|
||||
export var itemsList;
|
||||
|
||||
|
|
@ -9,17 +11,18 @@
|
|||
</script>
|
||||
|
||||
|
||||
<div class="items" class:items-list={itemsList}>
|
||||
<div class="items" class:items-list={itemsList} use:autoAnimate>
|
||||
{#each entries as entry}
|
||||
{@const title = entry.attributes.title.en || entry.attributes.title.ja || Object.values(entry.attributes.title)[0]}
|
||||
<a href="/{entry.id}" class="item" class:r18={!["safe", "suggestive"].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.cloud/https://uploads.mangadex.org/covers/{entry.id}/{entry.relationships.find(t => t.type === "cover_art").attributes.fileName}.512.jpg" alt="">
|
||||
<img class="cover" draggable="false" src="https://cors-anywhere.danbulant.cloud/https://uploads.mangadex.org/covers/{entry.id}/{entry.relationships.find(t => t.type === "cover_art").attributes.fileName}.512.jpg" alt="{title}" {title}>
|
||||
{:else}
|
||||
Broken art
|
||||
{/if}
|
||||
<div class="info">
|
||||
<h3>{entry.attributes.title.en || entry.attributes.title.ja || Object.values(entry.attributes.title)[0]}</h3>
|
||||
<h3>{title}</h3>
|
||||
{#if entry.attributes.lastChapter}
|
||||
<span>CH {entry.attributes.lastChapter}</span>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,12 @@ function display(formatted, type) {
|
|||
const error = console.error.bind(console);
|
||||
window.console.error = (...args) => {
|
||||
error(...args);
|
||||
display(JSON.stringify(args), "error");
|
||||
args = args.map(arg => {
|
||||
if(typeof arg === "string") return arg;
|
||||
if(arg instanceof Error) return arg.message + "\n" + arg.stack;
|
||||
return JSON.stringify(arg);
|
||||
});
|
||||
display(args.join("\n"), "error");
|
||||
}
|
||||
|
||||
window.onerror = (event, SourceBuffer, line, col, error) => {
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
{#if $logs.length}
|
||||
<div class="flow">
|
||||
{#each $logs as item}
|
||||
<div class="item {item.type}">
|
||||
{item.text}
|
||||
</div>
|
||||
<pre class="item {item.type}">{item.text}</pre>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -37,4 +35,7 @@
|
|||
padding: 5px;
|
||||
box-shadow: 0 0 2px 0 black;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -7,13 +7,17 @@
|
|||
import ListOrGrid from "../components/listOrGrid.svelte";
|
||||
import ratelimit from '../util/ratelimit';
|
||||
import MangadexItems from '../components/mangadexItems.svelte';
|
||||
|
||||
|
||||
/** @type {string} */
|
||||
var name = $params.search;
|
||||
$: {
|
||||
const url = new URL(window.location.toString());
|
||||
url.searchParams.set("search", name || "");
|
||||
history.replaceState(history.state, "", url.toString());
|
||||
}
|
||||
|
||||
var allowNSFW = false;
|
||||
|
||||
const filters = {
|
||||
contentRating: ["safe", "suggestive"],
|
||||
demographic: [],
|
||||
|
|
@ -21,6 +25,9 @@
|
|||
sort: "updatedAt",
|
||||
sortValue: "desc"
|
||||
};
|
||||
|
||||
filters.contentRating = allowNSFW ? [] : ["safe", "suggestive"];
|
||||
|
||||
/**
|
||||
* Searches for results
|
||||
* @param {string} title
|
||||
|
|
@ -91,16 +98,17 @@
|
|||
|
||||
function open() {
|
||||
var id = name;
|
||||
if(name.startsWith("https://mangadex.org/title/")) {
|
||||
id = name.substring("https://mangadex.org/title/".length);
|
||||
id = id.split("/")[0];
|
||||
} else if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(name)) {
|
||||
if(id.startsWith("https://mangadex.org/title/")) {
|
||||
id = id.substring("https://mangadex.org/title/".length);
|
||||
id = id.match(/[^\/?#]*/)[0];
|
||||
}
|
||||
if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id)) {
|
||||
return alert("You provided invalid ID or link. Make sure you copy the full URL from mangadex.org title page");
|
||||
}
|
||||
$goto("./" + id);
|
||||
}
|
||||
|
||||
const anilistID = window.location.hostname === "localhost" ? "8375" : "8374";
|
||||
const anilistID = window.location.hostname === "manga.danbulant.eu" ? "8374" : "8375";
|
||||
|
||||
let userDetails = isLogedIn() && getUserDetails();
|
||||
let userManga = isLogedIn() && getUserManga();
|
||||
|
|
@ -124,10 +132,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<div>
|
||||
<button on:click={randomManga} disabled={randomMangaLoading}>Random</button>
|
||||
<a href="https://discord.gg/XKPbz5xRuK">Made by TechmandanCZ#3372</a>
|
||||
</div>
|
||||
<button on:click={randomManga} disabled={randomMangaLoading}>Random</button>
|
||||
{#if isLogedIn()}
|
||||
{#await userDetails then userDetails}
|
||||
<a href="https://anilist.co/user/{userDetails.data.User.name}" target="_blank">
|
||||
|
|
@ -141,7 +146,17 @@
|
|||
</div>
|
||||
|
||||
{#if isLogedIn()}
|
||||
<ListOrGrid bind:list={listStyle} />
|
||||
<div class="nsfw">
|
||||
<input id="nsfw" type="checkbox" bind:checked={allowNSFW}>
|
||||
<label for="nsfw">
|
||||
Allow NSFW
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<a href="https://discord.gg/XKPbz5xRuK">Made by TechmandanCZ#3372</a>
|
||||
<ListOrGrid bind:list={listStyle} />
|
||||
</div>
|
||||
|
||||
{#if result}
|
||||
<h2>Search results</h2>
|
||||
|
|
@ -162,7 +177,7 @@
|
|||
{/if}
|
||||
{:else}
|
||||
<p>
|
||||
Sign in via Anilist to view your manga list and search for manga online.
|
||||
Sign in via Anilist to view your manga list and search for manga online. You can still read manga or download it without signing in using direct mangadex URLs.
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
|
|
@ -190,6 +205,10 @@
|
|||
</main>
|
||||
|
||||
<style lang="postcss">
|
||||
.nsfw > input, .nsfw > label {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
}
|
||||
.avatar {
|
||||
border-radius: 999px;
|
||||
height: 4rem;
|
||||
|
|
|
|||
3
src/util/dark.js
Normal file
3
src/util/dark.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { writable } from 'svelte-local-storage-store';
|
||||
|
||||
export const darkmode = writable("theme", "light");
|
||||
Loading…
Reference in a new issue