MangaParty: self-hosted manga/comic/webtoon reader

Zero-dependency Node server + plain HTML/JS frontend.

- Library is a folder tree (Manga/Book/Chapter/pages), indexed in place;
  page roles (cover, double, extra, rotation) are file name tags
- Accounts with per-user progress, reading settings, follows and
  new-chapter notifications (in-app + optional webhook)
- Reader with Flow, Page and Book modes, pointer-anchored page zoom,
  tap zones, auto-hiding controls, chapter picker, page preloading
- Multiple versions per chapter with community votes
- Docker image and compose file
- Demo library generator (tools/make-dummy.js)
- Docs: architecture, library format, import, scraper guide
This commit is contained in:
Maashkinoozhe committed 2026-10-01 09:35:05 +02:00
commit 8dd776b7f4
29 files changed
+3499

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>MangaParty</title>
<link rel="stylesheet" href="app.css">
<link rel="icon" href="icon.svg">
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#0b0b0c">
<script src="common.js" defer></script>
<script src="reader.js" defer></script>
</head>
<body class="reader">
<div id="stage" tabindex="-1"><div id="canvas"><p class="loading">Loading…</p></div></div>
<div id="top" class="bar">
<a id="back" class="btn icon" href="./" title="Back to the manga" aria-label="Back">‹</a>
<div id="title" class="grow"></div>
<select id="chsel" title="Jump to a chapter" aria-label="Chapter"></select>
<button id="fs" class="btn icon" title="Fullscreen" aria-label="Fullscreen"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/></svg></button>
</div>
<div id="bot" class="bar">
<div class="row">
<input id="slider" type="range" min="1" max="1" value="1" aria-label="Page">
<span id="pageno"></span>
</div>
<div id="tools">
<a id="prevch" class="btn" title="Previous chapter">‹<span class="wide-only"> Prev</span></a>
<div id="modes" class="seg" role="group" aria-label="View mode">
<button data-mode="flow" title="Continuous flow: all pages below each other">Flow</button>
<button data-mode="page" title="One page at a time">Page</button>
<button data-mode="book" title="Two pages side by side, like an open book">Book</button>
</div>
<button id="shift" class="btn" title="Page pairs look wrong? Shift them by one page">⇄<span class="wide-only"> Shift</span></button>
<button id="zoom" class="btn" title="Page zoom (Ctrl + scroll or pinch). Click to fit the screen again.">100%</button>
<select id="ver" title="Version of this chapter" aria-label="Version"></select>
<a id="nextch" class="btn" title="Next chapter"><span class="wide-only">Next </span>›</a>
</div>
</div>
<div id="toast"></div>
</body>
</html>