various small improvements

This commit is contained in:
Daniel Bulant 2022-09-05 18:50:35 +02:00
parent 30cb06bd0b
commit 44b3e042bb
8 changed files with 77 additions and 34 deletions

View file

@ -20,6 +20,7 @@ main
{ {
max-width: 600px; max-width: 600px;
margin: auto; margin: auto;
padding: 0 20px;
} }
a { a {

View file

@ -26,15 +26,15 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^19.0.2", "@rollup/plugin-commonjs": "^19.0.2",
"@rollup/plugin-node-resolve": "13.0.0", "@rollup/plugin-node-resolve": "13.0.0",
"@roxi/routify": "^2.18.4", "@roxi/routify": "^2.18.8",
"@types/streamsaver": "^2.0.1", "@types/streamsaver": "^2.0.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fs-extra": "^10.0.0", "fs-extra": "^10.1.0",
"nollup": "^0.16.5", "nollup": "^0.16.5",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.4.5", "postcss": "^8.4.16",
"postcss-import": "^14.0.2", "postcss-import": "^14.1.0",
"rollup": "^2.63.0", "rollup": "^2.79.0",
"rollup-plugin-hot": "^0.1.1", "rollup-plugin-hot": "^0.1.1",
"rollup-plugin-livereload": "^2.0.5", "rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-svelte": "^7.1.0", "rollup-plugin-svelte": "^7.1.0",
@ -43,8 +43,8 @@
"rollup-plugin-workbox": "^5.2.1", "rollup-plugin-workbox": "^5.2.1",
"spank": "^1.9.0", "spank": "^1.9.0",
"spassr": "^2.6.0", "spassr": "^2.6.0",
"svelte": "^3.45.0", "svelte": "^3.50.0",
"svelte-preprocess": "^4.10.1", "svelte-preprocess": "^4.10.7",
"tossr": "^1.4.2" "tossr": "^1.4.2"
}, },
"routify": { "routify": {
@ -57,9 +57,11 @@
] ]
}, },
"dependencies": { "dependencies": {
"@formkit/auto-animate": "1.0.0-beta.3",
"fflate": "^0.6.10", "fflate": "^0.6.10",
"streamsaver": "^2.0.5", "streamsaver": "^2.0.6",
"svelte-markdown": "^0.2.2", "svelte-local-storage-store": "^0.3.1",
"swiper": "^8.1.5" "svelte-markdown": "^0.2.3",
"swiper": "^8.3.2"
} }
} }

View file

@ -1,6 +1,7 @@
<script> <script>
import request from "../util/request";
import { goto } from '@roxi/routify/runtime/helpers'; import { goto } from '@roxi/routify/runtime/helpers';
import autoAnimate from "@formkit/auto-animate";
import request from "../util/request";
export var entries; export var entries;
export var itemsList; export var itemsList;
@ -12,7 +13,15 @@
query.set("title", entry.media.title.romaji); query.set("title", entry.media.title.romaji);
query.set("limit", 20); query.set("limit", 20);
console.log(entry); 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); console.log(result.data);
let item = result.data.find(t => t.attributes.links.al === entry.media.id.toString()); 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()); 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()))); 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); console.log(item);
if(!item) { if(!item) {
alert(`Couldn't find any mangadex entry`); alert(`Couldn't find any mangadex entry.`);
isLoading = false; isLoading = false;
return return
} }
@ -34,11 +43,11 @@
</dialog> </dialog>
{/if} {/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} {#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="item" class:r18={entry.media.isAdult} on:click={() => find(entry)}>
<div class="flex"> <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"> <div class="info">
<h3>{entry.media.title.userPreferred}</h3> <h3>{entry.media.title.userPreferred}</h3>
<span>[{entry.progress}/{entry.media.chapters || "?"}]</span> <br> <span>[{entry.progress}/{entry.media.chapters || "?"}]</span> <br>

View file

@ -1,5 +1,7 @@
<script> <script>
import SvelteMarkdown from "svelte-markdown"; import SvelteMarkdown from "svelte-markdown";
import autoAnimate from "@formkit/auto-animate";
export var entries; export var entries;
export var itemsList; export var itemsList;
@ -9,17 +11,18 @@
</script> </script>
<div class="items" class:items-list={itemsList}> <div class="items" class:items-list={itemsList} use:autoAnimate>
{#each entries as entry} {#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)}> <a href="/{entry.id}" class="item" class:r18={!["safe", "suggestive"].includes(entry.attributes.contentRating)} on:click={() => open(entry)}>
<div class="flex"> <div class="flex">
{#if entry.relationships.find(t => t.type === "cover_art")} {#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} {:else}
Broken art Broken art
{/if} {/if}
<div class="info"> <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} {#if entry.attributes.lastChapter}
<span>CH {entry.attributes.lastChapter}</span> <span>CH {entry.attributes.lastChapter}</span>
{/if} {/if}

View file

@ -27,7 +27,12 @@ function display(formatted, type) {
const error = console.error.bind(console); const error = console.error.bind(console);
window.console.error = (...args) => { window.console.error = (...args) => {
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) => { window.onerror = (event, SourceBuffer, line, col, error) => {

View file

@ -20,9 +20,7 @@
{#if $logs.length} {#if $logs.length}
<div class="flow"> <div class="flow">
{#each $logs as item} {#each $logs as item}
<div class="item {item.type}"> <pre class="item {item.type}">{item.text}</pre>
{item.text}
</div>
{/each} {/each}
</div> </div>
{/if} {/if}
@ -37,4 +35,7 @@
padding: 5px; padding: 5px;
box-shadow: 0 0 2px 0 black; box-shadow: 0 0 2px 0 black;
} }
pre {
white-space: pre-wrap;
}
</style> </style>

View file

@ -7,13 +7,17 @@
import ListOrGrid from "../components/listOrGrid.svelte"; import ListOrGrid from "../components/listOrGrid.svelte";
import ratelimit from '../util/ratelimit'; import ratelimit from '../util/ratelimit';
import MangadexItems from '../components/mangadexItems.svelte'; import MangadexItems from '../components/mangadexItems.svelte';
/** @type {string} */
var name = $params.search; var name = $params.search;
$: { $: {
const url = new URL(window.location.toString()); const url = new URL(window.location.toString());
url.searchParams.set("search", name || ""); url.searchParams.set("search", name || "");
history.replaceState(history.state, "", url.toString()); history.replaceState(history.state, "", url.toString());
} }
var allowNSFW = false;
const filters = { const filters = {
contentRating: ["safe", "suggestive"], contentRating: ["safe", "suggestive"],
demographic: [], demographic: [],
@ -21,6 +25,9 @@
sort: "updatedAt", sort: "updatedAt",
sortValue: "desc" sortValue: "desc"
}; };
filters.contentRating = allowNSFW ? [] : ["safe", "suggestive"];
/** /**
* Searches for results * Searches for results
* @param {string} title * @param {string} title
@ -91,16 +98,17 @@
function open() { function open() {
var id = name; var id = name;
if(name.startsWith("https://mangadex.org/title/")) { if(id.startsWith("https://mangadex.org/title/")) {
id = name.substring("https://mangadex.org/title/".length); id = id.substring("https://mangadex.org/title/".length);
id = id.split("/")[0]; id = id.match(/[^\/?#]*/)[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(!/^[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"); return alert("You provided invalid ID or link. Make sure you copy the full URL from mangadex.org title page");
} }
$goto("./" + id); $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 userDetails = isLogedIn() && getUserDetails();
let userManga = isLogedIn() && getUserManga(); let userManga = isLogedIn() && getUserManga();
@ -124,10 +132,7 @@
</div> </div>
<div class="flex"> <div class="flex">
<div> <button on:click={randomManga} disabled={randomMangaLoading}>Random</button>
<button on:click={randomManga} disabled={randomMangaLoading}>Random</button>
<a href="https://discord.gg/XKPbz5xRuK">Made by TechmandanCZ#3372</a>
</div>
{#if isLogedIn()} {#if isLogedIn()}
{#await userDetails then userDetails} {#await userDetails then userDetails}
<a href="https://anilist.co/user/{userDetails.data.User.name}" target="_blank"> <a href="https://anilist.co/user/{userDetails.data.User.name}" target="_blank">
@ -141,7 +146,17 @@
</div> </div>
{#if isLogedIn()} {#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} {#if result}
<h2>Search results</h2> <h2>Search results</h2>
@ -162,7 +177,7 @@
{/if} {/if}
{:else} {:else}
<p> <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> </p>
{/if} {/if}
@ -190,6 +205,10 @@
</main> </main>
<style lang="postcss"> <style lang="postcss">
.nsfw > input, .nsfw > label {
display: inline-block;
width: auto;
}
.avatar { .avatar {
border-radius: 999px; border-radius: 999px;
height: 4rem; height: 4rem;

3
src/util/dark.js Normal file
View file

@ -0,0 +1,3 @@
import { writable } from 'svelte-local-storage-store';
export const darkmode = writable("theme", "light");