commit 92b2d6d09e8306f2e6b8af0b17cbb6dd48bebd5c
Author: zhetic <>
Date: Sun Apr 11 01:08:27 2021 +0300
pretty much complete rewrite
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..30a8003
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Mangaloid
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/about.html b/about.html
new file mode 100644
index 0000000..e4a8f60
--- /dev/null
+++ b/about.html
@@ -0,0 +1,24 @@
+
+
+ Mangaloid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/catalog.html b/catalog.html
new file mode 100644
index 0000000..f655ffd
--- /dev/null
+++ b/catalog.html
@@ -0,0 +1,47 @@
+
+
+ Mangaloid
+
+
+
+
+
+
+
+
+
+
+
Recently updated
+
+
+
+
+
+
+ Title
+ Artist/Author
+ Status
+ Chapters
+ Updated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/css/chapter_list.css b/css/chapter_list.css
new file mode 100644
index 0000000..c008c4d
--- /dev/null
+++ b/css/chapter_list.css
@@ -0,0 +1,58 @@
+#info {
+ box-sizing: border-box;
+ width: 100%;
+ height: 25em;
+ border-top: 1em solid var(--light-grey);
+ border-bottom: 1em solid var(--light-grey);
+ border-left: 3em solid var(--light-grey);
+ border-right: 3em solid var(--light-grey);
+ background-color: var(--medium-grey);
+}
+
+#info #cover {
+ height: 23em;
+ width: 16em;
+ float: left;
+}
+
+#info .subtitle {
+ font-size: 14px;
+}
+
+#info #text {
+ position: absolute;
+ box-sizing: border-box;
+ left: 19em;
+ border-left: 2em solid var(--medium-grey);
+ border-right: 2em solid var(--medium-grey);
+ width: calc(100% - 16em - 6em);
+ word-wrap: break-word;
+}
+
+#chapters #table {
+ width: 90%;
+ border-collapse: collapse;
+ text-align: left;
+}
+
+#chapters #table .stretch {
+ width: 99%;
+}
+
+table, th, td {
+ border-collapse: collapse;
+ text-align: left;
+ white-space: nowrap;
+ padding-left: 1em;
+}
+
+
+th {
+ font-size: 12px;
+}
+
+tr {
+ border-bottom: 1px solid black;
+}
+
+
diff --git a/css/reader.css b/css/reader.css
new file mode 100644
index 0000000..14a44e1
--- /dev/null
+++ b/css/reader.css
@@ -0,0 +1,102 @@
+#titlebar_container {
+ z-index: 99;
+ position: absolute;
+ width: 100%;
+ height: 200px;
+}
+
+#titlebar {
+ z-index: 98;
+ text-align: center;
+ border-radius: 4px;
+ position: relative;
+ border: 1px solid var(--dark-grey);
+ transform: translate(-50%, -50%);
+ background-color: var(--medium-grey);
+ left: 50%;
+ width: 80%;
+ height: 40px;
+ margin-top: 30px;
+}
+
+#titlebar .text {
+ margin: 10px;
+ float: left;
+ color: black;
+}
+
+#titlebar button {
+ background-color: var(--transparent);
+ float: right;
+ border: none;
+ border-radius: 0;
+ box-shadow: none;
+ height: 40px;
+ width: 40px;
+}
+
+#titlebar .back {
+ float: left;
+}
+
+#titlebar img.back {
+ width: 15px;
+ height: 15px;
+}
+
+#titlebar img {
+ width: 20px;
+ height: 20px;
+}
+
+.image_fill {
+ position: absolute;
+ margin: auto;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ top: 0;
+ z-index: 95;
+}
+
+.image_left {
+ position: absolute;
+ width: 50%;
+ height: auto;
+ top : 0;
+ right: 50%;
+ z-index: 96;
+}
+
+.image_right {
+ position: absolute;
+ width: 50%;
+ height: auto;
+ top: 0;
+ left: 50%;
+ z-index: 96;
+}
+
+#page_left {
+ position: absolute;
+ height: 100%;
+ width: 50%;
+ left: 0%;
+ z-index: 97;
+}
+
+#page_right {
+ position: absolute;
+ height: 100%;
+ width: 50%;
+ left:50%;
+ z-index: 97;
+}
+
+#footer {
+ z-index: 98;
+ position: fixed;
+ bottom: 0;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
diff --git a/css/search.css b/css/search.css
new file mode 100644
index 0000000..e01ef0e
--- /dev/null
+++ b/css/search.css
@@ -0,0 +1,43 @@
+#search {
+ position: relative;
+ width: 100%;
+ height: 25em;
+ top: 2em;
+ left: 0;
+}
+
+#search input, p {
+ position: relative;
+ display: table-cell;
+ margin: 4px;
+}
+
+#search div {
+ display: table;
+ width: 100%;
+ height: 4em;
+}
+
+#search p {
+ width: 3em;
+ white-space: nowrap;
+}
+
+#search .one input {
+ width: 99%;
+}
+
+#search .two input {
+ width: 98%;
+}
+
+#search .three input {
+ width: 99%;
+}
+
+#search button {
+ padding: 1em;
+ top: 17em;
+}
+
+
diff --git a/css/stylesheet.css b/css/stylesheet.css
new file mode 100644
index 0000000..35f824f
--- /dev/null
+++ b/css/stylesheet.css
@@ -0,0 +1,121 @@
+body {
+ font-family: arial, helvetica, sans-serif;
+ --dark-grey: rgba(80, 80, 80, 1);
+ --medium-grey: rgba(120, 120, 120, 1);
+ --light-accent: rgba(150, 150, 150, 1);
+ --light-grey: rgba(180, 180, 180, 1);
+ --red-accent: rgba(167, 7, 7, 1);
+ --transparent: rgba(0, 0, 0, 0);
+ background-color: var(--light-grey);
+}
+
+button {
+ background-color: var(--light-accent);
+ border: none;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-radius: 1em;
+ vertical-align: center;
+ outline: none;
+ cursor: pointer;
+ box-shadow: 0 2px var(--dark-grey);
+}
+
+button:active {
+ transform: translateY(2px);
+ box-shadow: 0 0;
+}
+
+input {
+ background-color: white;
+ border: none;
+ padding: 1em;
+ border-radius: 1em;
+ outline: none;
+}
+
+hr {
+ border: 1px solid var(--light-grey);
+}
+
+a {
+ text-decoration: none;
+}
+
+#header {
+ position: fixed;
+ top: 0%;
+ left: 0%;
+ width: 100%;
+ height: 5em;
+ background-color: var(--medium-grey);
+ z-index: 100;
+ overflow: hidden;
+}
+
+#header #home {
+ position: relative;
+ top: 30%;
+ height: 40%;
+ left: 2em;
+}
+
+#header #search_bar {
+ position: absolute;
+ transform: translateY(50%);
+ background-color: white;
+ border: none;
+ padding: 1em;
+ border-radius: 1em;
+ left: 10em;
+ width: 50%;
+ height: 50%;
+}
+
+#header #search_button {
+ position: absolute;
+ height: 50%;
+ left: calc(10em + 50% + 1em);
+ transform: translateY(50%);
+}
+
+#header #logo {
+ position: absolute;
+ height: 180%;
+ right: 5%;
+}
+
+#content {
+ position: absolute;
+ width: 80%;
+ left: 10%;
+ top: 5em;
+ bottom: 0em;
+}
+
+.tag {
+ border: 1px solid black;
+ background-color: var(--light-accent);
+ padding: 4px;
+ margin: 1px;
+ border-radius: 5px;
+}
+
+@media only screen and (max-width: 800px){
+ #content {
+ width: 800px;
+ left: 0;
+ }
+ #logo {
+ visibility: hidden;
+ }
+}
+
+#content #footer {
+ position: relative;
+ height: 10em;
+}
+
+
+
+
diff --git a/css/title_list.css b/css/title_list.css
new file mode 100644
index 0000000..8f83214
--- /dev/null
+++ b/css/title_list.css
@@ -0,0 +1,55 @@
+#title_list {
+ position: relative;
+ width: 100%;
+ left: 0;
+ top: 0em;
+}
+
+#label {
+ position: relative;
+ left: 0;
+ top: 0;
+}
+
+td {
+ white-space: nowrap;
+ padding-left: 2em;
+ padding-right: 2em;
+}
+
+table, th, td {
+ border-collapse: collapse;
+}
+table, th {
+ width: 100%;
+}
+
+th {
+ font-size: 12px;
+}
+
+.first_row {
+ border-top: 1px solid black;
+ padding-top: 2em;
+}
+
+.second_row {
+ border-bottom: 1px solid black;
+ padding-bottom 2em;
+}
+
+#title_list img.thumbnail {
+ height: 100px;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+
+#title_list .tag {
+ border: 1px solid black;
+ background-color: var(--light-accent);
+ padding: 4px;
+ margin: 1px;
+ border-radius: 5px;
+}
diff --git a/img/back.png b/img/back.png
new file mode 100644
index 0000000..837a438
Binary files /dev/null and b/img/back.png differ
diff --git a/img/covers/1.jpg b/img/covers/1.jpg
new file mode 100644
index 0000000..0a5b74a
Binary files /dev/null and b/img/covers/1.jpg differ
diff --git a/img/covers/2.jpg b/img/covers/2.jpg
new file mode 100644
index 0000000..5b658b6
Binary files /dev/null and b/img/covers/2.jpg differ
diff --git a/img/covers/3.jpg b/img/covers/3.jpg
new file mode 100644
index 0000000..e2e5158
Binary files /dev/null and b/img/covers/3.jpg differ
diff --git a/img/covers/4.jpg b/img/covers/4.jpg
new file mode 100644
index 0000000..66f9125
Binary files /dev/null and b/img/covers/4.jpg differ
diff --git a/img/double.png b/img/double.png
new file mode 100644
index 0000000..5bcbed2
Binary files /dev/null and b/img/double.png differ
diff --git a/img/download.png b/img/download.png
new file mode 100644
index 0000000..e218716
Binary files /dev/null and b/img/download.png differ
diff --git a/img/height.png b/img/height.png
new file mode 100644
index 0000000..2ada78d
Binary files /dev/null and b/img/height.png differ
diff --git a/img/home.png b/img/home.png
new file mode 100644
index 0000000..d8ed7fb
Binary files /dev/null and b/img/home.png differ
diff --git a/img/logo.png b/img/logo.png
new file mode 100644
index 0000000..e31240a
Binary files /dev/null and b/img/logo.png differ
diff --git a/img/logo_fullsize.png b/img/logo_fullsize.png
new file mode 100644
index 0000000..1c60307
Binary files /dev/null and b/img/logo_fullsize.png differ
diff --git a/img/mangaupdates.ico b/img/mangaupdates.ico
new file mode 100644
index 0000000..fd946fc
Binary files /dev/null and b/img/mangaupdates.ico differ
diff --git a/img/single.png b/img/single.png
new file mode 100644
index 0000000..47dfd2a
Binary files /dev/null and b/img/single.png differ
diff --git a/img/width.png b/img/width.png
new file mode 100644
index 0000000..d07a9a1
Binary files /dev/null and b/img/width.png differ
diff --git a/js/chapter_list.js b/js/chapter_list.js
new file mode 100644
index 0000000..742bd9d
--- /dev/null
+++ b/js/chapter_list.js
@@ -0,0 +1,114 @@
+// ----------------------------------------------------
+// Fetch metadata for one title and fill out a page
+// ----------------------------------------------------
+
+function load_info(remote, id) {
+ remote += "/manga/from_id?id=" + id;
+ fetch(remote)
+ .then(manga => manga.json())
+ .then(function (manga) {
+ var text = document.querySelector("#info #text");
+ document.getElementById("cover").src = remote+"/manga/thumbnail?id="+id;
+
+ text.appendChild(Object.assign(
+ document.createElement("h2"),
+ {textContent: manga["titles"][0]}
+ ));
+ text.appendChild(Object.assign(
+ document.createElement("span"),
+ {textContent: get_utf_kanji(manga["titles"].slice(1).join(" | ")), className: "subtitle"}
+ ));
+
+ text.appendChild(document.createElement("hr"));
+
+ text.appendChild(Object.assign(
+ document.createElement("p"),
+ {textContent: "Artist(s): " + manga["artists"].join(", ")}
+ ));
+
+ text.appendChild(Object.assign(
+ document.createElement("p"),
+ {textContent: "Author(s): " + manga["authors"].join(", ")}
+ ));
+
+ text.appendChild(Object.assign(
+ document.createElement("p"),
+ {textContent: "Status: " + manga["publication_status"]}
+ ));
+
+ text.appendChild(Object.assign(
+ document.createElement("p"),
+ {textContent: "Last Updated: "}
+ ));
+
+ var tags = document.createElement("p");
+ text.appendChild(tags);
+ manga["genres"].forEach(tag => {
+ tags.appendChild(Object.assign(
+ document.createElement("span"),
+ {className: "tag", textContent: tag}
+ ));
+ });
+ });
+}
+
+function load_chapters(remote, id) {
+ remote += "/manga/get_chapters?id=" + id;
+ fetch(remote)
+ .then(res => res.json())
+ .then(function (res) {
+ var table = document.querySelector("#chapters #table tbody");
+
+ res.forEach(function (chapter, index) {
+ var row = table.appendChild(document.createElement("tr"));
+
+ //number
+ row.appendChild(document.createElement("td"))
+ .appendChild(Object.assign(
+ document.createElement("p"),
+ {textContent: chapter["chapter_no"]+"."+chapter["chapter_postfix"]}
+ ));
+
+ //title
+ row.appendChild(document.createElement("td"))
+ .appendChild(Object.assign(
+ document.createElement("a"),
+ {textContent: chapter["title"], href: "./reader.html?cid="+chapter["ipfs_link"]+"&pages="+chapter["page_count"]+"&title="+chapter["title"].replaceAll(" ", "+")}
+ ));
+
+ //group
+ row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: chapter["group_id"]}
+ ));
+
+ //page count
+ row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: chapter["page_count"]}
+ ));
+
+ //date
+ row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: new Date(chapter["date_added"]).toLocaleString()}
+ ));
+ });
+ });
+}
+
+function get_utf_kanji(str) {
+ return str.replace(
+ /[\uff01-\uff5e]/g,
+ function(ch) { return String.fromCharCode(ch.charCodeAt(0) - 0xfee0); }
+ );
+}
+
+function load(remote){
+ var url = new URL(window.location.href);
+ if(url.searchParams.has("id")){
+ var id = url.searchParams.get("id");
+ load_info(remote, id);
+ load_chapters(remote, id);
+ }
+}
diff --git a/js/reader.js b/js/reader.js
new file mode 100644
index 0000000..4b5ce1a
--- /dev/null
+++ b/js/reader.js
@@ -0,0 +1,223 @@
+var layoutCurrent;
+var pageNo = 0;
+var pageCurrent = 1;
+var title;
+var cid;
+var fitCurrent;
+var url = new URL(window.location.href);
+var manga = 0;
+var chapter = 0;
+
+// ---------------------------------------------------------
+// Functions
+// ---------------------------------------------------------
+
+//set page to pageCurrent and changer the counter
+function loadPage() {
+ if(pageCurrent <= pageNo && pageCurrent > 0){
+ for(var i = 1; i <= pageNo; i++){
+ document.getElementById(`image${i}`).style.visibility = "hidden";
+ }
+ if(layoutCurrent == "double"){
+ if(pageCurrent%2==0){
+ pageCurrent--;
+ }
+ var pagePair = pageCurrent+1;
+ document.getElementById(`image${pagePair}`).style.visibility = "visible";
+ }
+ document.querySelector("#footer #counter").textContent = `${pageCurrent}/${pageNo}`;
+ document.getElementById(`image${pageCurrent}`).style.visibility = "visible";
+ }
+}
+
+// Goto next page or previous page. Left is next page by default.
+var rightPage = function () {
+ if(layoutCurrent == "double"){
+ if(pageCurrent+2 <= pageNo){
+ pageCurrent += 2;
+ }
+ }
+ else{
+ if(pageCurrent+1 <= pageNo){
+ pageCurrent++;
+ }
+ }
+ loadPage();
+}
+
+var leftPage = function () {
+ if(layoutCurrent == "double"){
+ if(pageCurrent-2 >= 1){
+ pageCurrent -= 2;
+ }
+ }
+ else{
+ if(pageCurrent-1 >= 1){
+ pageCurrent--;
+ }
+ }
+ loadPage();
+}
+
+// Inversion between left-to-right and right-to-left
+function invertPage() {
+ [leftPage, rightPage] = [rightPage, leftPage];
+}
+
+function layoutSingle(){
+ layoutCurrent = "single";
+ fitHeight();
+ for (let i = 1; i <= pageNo; i++) {
+ document.getElementById(`image${i}`).className = "image_fill";
+ }
+ document.querySelector("#titlebar img.layout").src = "img/single.png";
+}
+
+function layoutDouble(){
+ fitHeight();
+ layoutCurrent = "double";
+ for (let i = 1; i <= pageNo; i++) {
+ let side = "right";
+ if(i%2==0){
+ side = "left";
+ }
+ document.getElementById(`image${i}`).className = `image_${side}`;
+ }
+ document.querySelector("#titlebar img.layout").src = "img/double.png";
+}
+
+function fitWidth(){
+ if(layoutCurrent == "single"){
+ fitCurrent = "width";
+ var items = document.getElementsByClassName("image_fill");
+ for(var i = 0; i < items.length; i++){
+ items.item(i).style.width = "100%";
+ items.item(i).style.height = "auto";
+ }
+ document.querySelector("#titlebar img.fit").src = "img/width.png";
+ }
+}
+
+function fitHeight(){
+ if(layoutCurrent == "single"){
+ fitCurrent = "height";
+ var items = document.getElementsByClassName("image_fill");
+ for(var i = 0; i < items.length; i++){
+ items.item(i).style.width = "auto";
+ items.item(i).style.height = "100%";
+ }
+ document.querySelector("#titlebar img.fit").src = "img/height.png";
+ }
+}
+
+// ---------------------------------------------------------
+// Event handlers
+// ---------------------------------------------------------
+
+document.addEventListener("keydown", function (e) {
+ e = e || window.event;
+ switch (e.keyCode) {
+ case 39:
+ case 76:
+ rightPage();
+ break;
+ case 37:
+ case 72:
+ leftPage();
+ break;
+ case 73:
+ invertPage();
+ default: return;
+ }
+ e.preventDefault();
+});
+
+document.querySelector("#page_left").addEventListener("click", function (e) {
+ leftPage();
+});
+
+document.querySelector("#page_right").addEventListener("click", function (e) {
+ rightPage();
+});
+
+document.querySelector("#titlebar button.download").addEventListener("click", function (e) {
+ //document.getElementById("downloadButton").style.background-color = "rgb(0, 0, 0, 0.2)";
+});
+
+document.querySelector("#titlebar button.layout").addEventListener("click", function (e) {
+ if(layoutCurrent == "single"){
+ layoutDouble();
+ }
+ else{
+ layoutSingle();
+ }
+ loadPage();
+});
+
+document.querySelector("#titlebar button.fit").addEventListener("click", function (e) {
+ if(fitCurrent == "height"){
+ fitWidth();
+ }
+ else{
+ fitHeight();
+
+ }
+ loadPage();
+});
+
+document.querySelector("#titlebar button.invert").addEventListener("click", function (e) {
+ invertPage();
+});
+
+document.querySelector("#titlebar_container").addEventListener("mouseenter", function () {
+ document.querySelector("#titlebar").style.visibility = "visible";
+});
+
+document.querySelector("#titlebar_container").addEventListener("mouseleave", function () {
+ document.querySelector("#titlebar").style.visibility = "hidden";
+});
+
+// ---------------------------------------------------------
+// parse metadata
+// ---------------------------------------------------------
+
+function load_pages() {
+ if(url.searchParams.has("cid")){
+ cid = url.searchParams.get("cid");
+ if(cid == ""){
+ return;
+ }
+ pageNo = url.searchParams.get("pages");
+ title = url.searchParams.get("title");
+
+ // "https://ipfs.io/api/v0/ls/"+res[manga][chapter]["cid"];
+
+ // --------------------------------------------------------
+ // Initialize
+ // --------------------------------------------------------
+
+ document.querySelector("#titlebar").style.visibility = "hidden";
+ document.querySelector("#footer #counter").textContent = `${pageCurrent}/${pageNo}`;
+ document.querySelector("#titlebar .text").textContent = `${title}`;
+
+ var pageView = document.querySelector("#page_view");
+ for (var i = 1; i <= pageNo; i++) {
+ pageView.appendChild(Object.assign(
+ document.createElement("img"),
+ {draggable: "false", src: `https://ipfs.cynic.moe/ipfs/${cid}/${i}.jpg`, id: `image${i}`, visibility: "hidden"}
+ ));
+ }
+
+ if(pageNo > 0){
+ layoutSingle();
+ fitHeight();
+ loadPage();
+ }
+ else{
+ document.querySelector("#titlebar #text").textContent = "Nothing to load";
+ }
+ }
+}
+
+
+
diff --git a/js/search.js b/js/search.js
new file mode 100644
index 0000000..e1da4d9
--- /dev/null
+++ b/js/search.js
@@ -0,0 +1,52 @@
+// ----------------------------------------------------
+// Search function
+// ----------------------------------------------------
+
+function search_full() {
+ var parameter = [];
+ //get search string
+ var title = document.querySelector("#search input.title").value;
+ if(title != ""){
+ title = title.toLowerCase().replaceAll(" ", "+");
+ parameter.push("title="+title);
+ }
+ //get author
+ var author = document.querySelector("#search input.author").value;
+ if(author != ""){
+ author = author.toLowerCase().split(",").map(s => s.trim()).map(s => s.replaceAll(" ", "+"));
+ parameter.push("authors="+author.join(","));
+ }
+ //get artist
+ var artist = document.querySelector("#search input.artist").value;
+ if(artist != ""){
+ artist = artist.toLowerCase().split(",").map(s => s.trim()).map(s => s.replaceAll(" ", "+"));
+ parameter.push("artists="+artist.join(","));
+ }
+ //get tags
+ var tag = document.querySelector("#search input.tags").value;
+ if(tag != ""){
+ tag = tag.toLowerCase().split(/(?=\+|\-)/).map(s => s.trim()).map(s => s.replaceAll(" ", "+"));
+ parameter.push("tags="+tag.join(","));
+ }
+ //sort
+ var sort = document.querySelector("#content select.sort").value;
+ if(sort != ""){
+ parameter.push("sortby="+sort);
+ }
+ var query = parameter.join("&");
+ return query;
+}
+
+// ----------------------------------------------------
+// Event handlers
+// ----------------------------------------------------
+
+var fields = document.getElementsByTagName("input");
+Array.from(fields).map(field => field.addEventListener("keydown", function (e) {
+ e = e || window.event;
+ if(e.keyCode == 13){
+ e.preventDefault();
+ search_full();
+ }
+}));
+
diff --git a/js/search_bar.js b/js/search_bar.js
new file mode 100644
index 0000000..1b8b2ca
--- /dev/null
+++ b/js/search_bar.js
@@ -0,0 +1,22 @@
+// -------------------------------------------------------------
+// Search bar function
+// -------------------------------------------------------------
+
+function search_bar() {
+ var query = document.querySelector("#header #search_bar").value;
+ if(query != ""){
+ query = query.toLowerCase().replaceAll(" ", "+");
+ var url = "https://amangathing.ddns.net/search.html?title=" + query;
+ console.log(query);
+ window.location.href = url;
+ }
+}
+
+document.querySelector("#header #search_bar").addEventListener("keydown", function (e) {
+ e = e || window.event;
+ if(e.keyCode == 13){
+ search_bar();
+ e.preventDefault();
+ }
+});
+
diff --git a/js/title_list.js b/js/title_list.js
new file mode 100644
index 0000000..87ae13f
--- /dev/null
+++ b/js/title_list.js
@@ -0,0 +1,116 @@
+// ----------------------------------------------------------------
+// Fetch metadata and create a table
+// ----------------------------------------------------------------
+
+function load_titles(remote) {
+ if(remote == ""){
+ return;
+ }
+ fetch(remote)
+ .then(res => res.json())
+ .then(function (res) {
+ var table = document.querySelector("#title_list #table tbody");
+ res.forEach(manga => {
+ //row 1
+ var first_row = document.createElement("tr");
+ first_row.className = "first_row";
+ table.appendChild(first_row);
+
+ //thumbnail
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {rowSpan: "2"}
+ ))
+ .appendChild(Object.assign(
+ document.createElement("a"),
+ {href: "./title.html?id="+manga["id"]}
+ ))
+ .appendChild(Object.assign(
+ document.createElement("img"),
+ {className: "thumbnail", src: "img/covers/"+manga["id"]+".jpg"}
+ ));
+
+ //title
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {}
+ ))
+ .appendChild(Object.assign(
+ document.createElement("b"),
+ {textContent: manga["titles"][0]}
+ ));
+
+ //artist
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: manga["artists"][0]}
+ ));
+
+ //status
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: manga["publication_status"]}
+ ));
+
+ //chapters
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: ""}
+ ));
+
+ //timestamp
+ first_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: ""}
+ ));
+
+ //row 2
+ var second_row = document.createElement("tr");
+ second_row.className = "second_row";
+ table.appendChild(second_row);
+
+ //tags
+ var tag_cell = document.createElement("td");
+ second_row.appendChild(tag_cell);
+ manga["genres"].forEach(tag => {
+ tag_cell.appendChild(Object.assign(
+ document.createElement("span"),
+ {className: "tag", textContent: tag}
+ ));
+ });
+
+ //author
+ second_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: manga["authors"][0]}
+ ));
+
+ //filler
+ second_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {colSpan: "2"}
+ ))
+ .appendChild(Object.assign(
+ document.createElement("a"),
+ {href: "https://mangaupdates.com/series.html?id=" + manga["mangaupdates_id"]}
+ ))
+ .appendChild(Object.assign(
+ document.createElement("img"),
+ {src: "img/mangaupdates.ico"}
+ ));
+
+ //time since last update
+ second_row.appendChild(Object.assign(
+ document.createElement("td"),
+ {textContent: "(" + "ago)"}
+ ));
+ });
+ });
+}
+
+function rm_titles() {
+ var par = document.querySelector("#title_list #table tbody");
+ while(par.firstChild()){
+ par.removeChild(par.firstChild());
+ }
+}
diff --git a/reader.html b/reader.html
new file mode 100644
index 0000000..5882d00
--- /dev/null
+++ b/reader.html
@@ -0,0 +1,53 @@
+
+
+ Mangaloid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/search.html b/search.html
new file mode 100644
index 0000000..f1b8be9
--- /dev/null
+++ b/search.html
@@ -0,0 +1,102 @@
+
+
+ Mangaloid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Artist:
+
+
+
Author:
+
+
+
+
+
+
Sort:
+
+ name
+ date
+ status
+
+
+
Search
+
+
+
+
+
+
+
+
+
+
+ Title
+ Artist/Author
+ Status
+ Chapters
+ Updated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/title.html b/title.html
new file mode 100644
index 0000000..0b19ac9
--- /dev/null
+++ b/title.html
@@ -0,0 +1,54 @@
+
+
+ Mangaloid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No.
+ Chapter
+ TL Group
+ Pages
+ Date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+