diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index fc2023f..c615263 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -240,7 +240,7 @@ "selectAProvider": "Select a provider", "bookLocked": "This book is locked", "thisisa": "This is a", - "Thisispartofthe": "This is part of the '", + "Thisispartofthe": "This is part of the", "pages": "pages", "series": "series", "READING": "READING", diff --git a/src/components/ContentViewer.tsx b/src/components/ContentViewer.tsx index 853e963..c948c83 100644 --- a/src/components/ContentViewer.tsx +++ b/src/components/ContentViewer.tsx @@ -1,13 +1,15 @@ import { PDP, currentProfile } from "@/utils/Common.ts"; -import { AllForOne, changeRating, downloadBook } from "@/utils/Fetchers.ts"; +import { AllForOne, changeRating, downloadBook, getFromDB } from "@/utils/Fetchers.ts"; import { IBook } from "@/utils/IBook.ts"; import { providerEnum } from "@/utils/utils.ts"; -import { AutoStories, Check, Close, Download, Edit, Favorite, PlayArrow, Refresh, YoutubeSearchedFor } from "@mui/icons-material"; -import { IconButton, Stack } from "@mui/material"; +import { AutoStories, Check, Close, Done, Download, Edit, Favorite, PlayArrow, Refresh, YoutubeSearchedFor } from "@mui/icons-material"; +import { Chip, IconButton, Stack } from "@mui/material"; import Rating from "@mui/material/Rating/Rating"; import Grid2 from "@mui/material/Unstable_Grid2/Grid2"; import { useEffect, useLayoutEffect, useState } from "react"; import { useTranslation } from "react-i18next"; +import { Toaster } from "./Toaster"; +import DatabaseEditorDialog from "./Dialogs/DatabaseEditorDialog"; //providerEnum to type type TProvider = providerEnum.Marvel | providerEnum.Anilist | providerEnum.MANUAL | providerEnum.OL | providerEnum.GBooks; function ContentViewer({ provider, TheBook, type, handleAddBreadcrumbs }: { @@ -43,8 +45,14 @@ function ContentViewer({ provider, TheBook, type, handleAddBreadcrumbs }: { handleAsyncBG(); }, [TheBook.URLCover]); console.log("TheBook", TheBook); - return (<> + const [openDatabaseEditorDialog, setOpenDatabaseEditorDialog] = useState(false); + + const handleCloseDatabaseEditorDialog = () => { + setOpenDatabaseEditorDialog(false); + }; + return (<> +
#
@@ -61,8 +69,48 @@ function ContentViewer({ provider, TheBook, type, handleAddBreadcrumbs }: { {TheBook.NOM} }
-

-
+ + + { + TheBook.read === 1 ? + } /> + : TheBook.unread === 1 ? + } /> + : TheBook.reading === 1 ? + } /> + : "" + + } + { + TheBook.favorite === 1 ? + } /> + : "" + } + + +
+ { + TheBook.dates !== "null" ? t("dates") + JSON.parse(TheBook.dates).map((date: {type: string; date: string; }, index: number) => { + return

{date.type.replace(/([A-Z])/g, ' $1').trim() + " : " + date.date}

; + }) : "" + } +
{ @@ -71,11 +119,86 @@ function ContentViewer({ provider, TheBook, type, handleAddBreadcrumbs }: { window.location.href = "viewer.html?" + encoded; } }> - - - - - + { + AllForOne("unread", "reading", "read", TheBook.ID_book); + Toaster(t("mkread"), "success"); + } + } + > + { + AllForOne("unread", "read", "reading", TheBook.ID_book); + Toaster(t("mkreading"), "success"); + } + } + > + { + AllForOne("read", "reading", "unread", TheBook.ID_book); + Toaster(t("mkunread"), "success"); + } + } + > + { + if (TheBook.favorite === 1) { + TheBook.favorite = 0; + Toaster(t("remove_fav"), "success"); + await getFromDB("Books", "* FROM Books WHERE favorite=1").then(async (resa) => { + if (!resa) return; + const bookList = JSON.parse(resa); + for (let i = 0; i < bookList.length; i++) { + if (bookList[i].PATH.toLowerCase().includes(TheBook.NOM.toLowerCase().replaceAll('"', ''))) { + const options = { + method: "POST", headers: { + "Content-Type": "application/json" + }, body: JSON.stringify({ + "token": currentProfile.getToken, + "table": "Books", + "column": "favorite", + "whereEl": bookList[i].PATH, + "value": false, + "where": "PATH" + }, null, 2) + }; + await fetch(PDP + "/DB/update", options); + } + } + }); + } else { + TheBook.favorite = 1; + Toaster(t("add_fav"), "success"); + await getFromDB("Books", "* FROM Books WHERE favorite=0").then(async (resa) => { + if (!resa) return; + const bookList = JSON.parse(resa); + for (let i = 0; i < bookList.length; i++) { + if (bookList[i].PATH.toLowerCase().includes(TheBook.NOM.toLowerCase().replaceAll('"', ''))) { + const options = { + method: "POST", headers: { + "Content-Type": "application/json" + }, body: JSON.stringify({ + "token": currentProfile.getToken, + "table": "Books", + "column": "favorite", + "whereEl": bookList[i].PATH, + "value": true, + "where": "PATH" + }, null, 2) + }; + await fetch(PDP + "/DB/update", options); + } + } + }); + } + } + } + > + {setOpenDatabaseEditorDialog(true)}} id="editmodalBtn"> { downloadBook(TheBook.PATH); @@ -137,13 +260,63 @@ function ContentViewer({ provider, TheBook, type, handleAddBreadcrumbs }: {
-
-
-
-
+
+ { + TheBook.issueNumber === (null || "null" || "") ? "" : t("Numberofthisvolumewithintheseries") + TheBook.issueNumber + } +
+
+ { + (TheBook.characters !== "null" && providerEnum.Marvel) ? + t("thisisa") + TheBook.format + " " + t("of") + " " + TheBook.pageCount + " " + t("pages") + t("Thisispartofthe")+" '" + JSON.parse(TheBook.series).name + "' " + t("series") : (provider === providerEnum.Anilist) ? + t("Thisispartofthe") + " '" + TheBook.series.split("_")[2].replaceAll("$", " ") + "' " + t("series") :(provider === providerEnum.Marvel) ? + t("Thisispartofthe") + " '" + JSON.parse(TheBook.series).name + "' " + t("series") : (provider === providerEnum.MANUAL) ? + t("Thisispartofthe") + " '" + TheBook.series + "' " + t("series") : (provider === providerEnum.OL) ? + t("Thisispartofthe") + " '" + TheBook.series + "' " + t("series") : (provider === providerEnum.GBooks) ?t("this is a") + TheBook.format + " " + t("of") + " " + TheBook.pageCount + " " + t("pages") + t("Thisispartofthe")+" '" + TheBook.series + "' " + t("series") : "" + } +
+
{ + TheBook.collectedIssues === 'null' ? "" : JSON.parse(TheBook.collectedIssues).map((issue: { name: string; }, index: number) => { + return

{issue.name}

; + }) + }
+
+ { + TheBook.collections === 'null' ? "" : JSON.parse(TheBook.collections).map((col: { name: string; }, index: number) => { + return

{col.name}

; + }) + } +
-
+ { + TheBook.characters !== "null" ?
{ + const options = { + method: "POST", headers: { + "Content-Type": "application/json" + }, body: JSON.stringify({ + "token": currentProfile.getToken, + "table": "Books", + "column": "last_page", + "whereEl": TheBook.ID_book, + "value": e.target.value, + "where": "ID_book" + }, null, 2) + }; + await fetch(PDP + "/DB/update", options).catch((err) => { + Toaster(err, "error"); + }); + } + } + />/ {TheBook.pageCount} {t('pagesRead')}
: "" + } +

Volumes :

diff --git a/src/components/Dialogs/DatabaseEditorDialog.tsx b/src/components/Dialogs/DatabaseEditorDialog.tsx index 9ec10d8..df382d7 100644 --- a/src/components/Dialogs/DatabaseEditorDialog.tsx +++ b/src/components/Dialogs/DatabaseEditorDialog.tsx @@ -6,12 +6,17 @@ import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; -import { useEffect } from "react"; +import { useEffect, useLayoutEffect } from "react"; import { useTranslation } from 'react-i18next'; +import { IBook } from '@/utils/IBook.ts'; +import { PDP, currentProfile } from '@/utils/Common.ts'; +import { Checkbox, FormControlLabel } from '@mui/material'; -export default function DatabaseEditorDialog({ onClose, openModal }: { +export default function DatabaseEditorDialog({ onClose, openModal, TheBook,type }: { onClose: any, openModal: boolean, + TheBook: IBook, + type : 'series' | 'book' }) { const [open, setOpen] = React.useState(openModal); const { t } = useTranslation(); @@ -25,146 +30,286 @@ export default function DatabaseEditorDialog({ onClose, openModal }: { onClose(); }; + useLayoutEffect(() => { + if (TheBook) { + document.querySelectorAll("#commonEdit>label>input").forEach((e:any) => { + e.value = TheBook[e.id.replaceAll("edit_", "")]; + }); + document.querySelectorAll("#bookEdit>label>input").forEach((e:any) => { + e.value = TheBook[e.id.replaceAll("edit_", "")]; + }); + } + },[]); + + const handleSend = async () => { + const values = []; + const columns = []; + document.querySelectorAll("#commonEdit>label>input").forEach((e: any) => { + values.push(e.value.replaceAll("'", "''").replaceAll('"', "'")); + columns.push(e.id.replaceAll("edit_", "")); + }); + document.querySelectorAll("#bookEdit>label>input").forEach((e:any) => { + values.push(e.value.replaceAll("'", "''").replaceAll('"', "'")); + columns.push(e.id.replaceAll("edit_", "")); + }); + const lockCheck = document.getElementById("lockCheck") as HTMLInputElement; + values.push(lockCheck ? lockCheck.checked : false); + columns.push("lock"); + await fetch(PDP + "/DB/update", { + method: "POST", headers: { + "Content-Type": "application/json" + }, body: JSON.stringify({ + "token": currentProfile.getToken, + "table": "Books", + "type": "edit", + "column": columns, + "whereEl": TheBook.PATH, + "value": values, + "where": "PATH" + }, null, 2) + }); + }; + return (
{t("EDIT")} -

Warning : Be careful when you modify those fields, DO NOT change the way they are written. If an item + Warning : Be careful when you modify those fields, DO NOT change the way they are written. If an item have '"', { } or [] at the beginning and at the end DO NOT remove them change only the content. The required fields have to respect this - pattern.

-
- - - - - - -
-
- - - - - - - - - - - - - - -
-
- - - - - - - - - -
+ pattern. +
- - +
+ } label="Lock this item ? (That prevent the metadata to be overwritten when refresh and disable rematch)" /> + + + +
+ {type === 'series' ? +
+ + + + + +
: type === 'book' ? +
+ +
: <>}
- +
diff --git a/src/static/collectionner.js b/src/static/collectionner.js index ff97d2c..b9c6c3b 100644 --- a/src/static/collectionner.js +++ b/src/static/collectionner.js @@ -1975,12 +1975,7 @@ async function createDetails(TheBook, provider) { title: language["rematch"], placement: "bottom" }); - document.querySelectorAll("#commonEdit>label>input").forEach((e) => { - e.value = TheBook[e.id.replaceAll("edit_", "")]; - }) - document.querySelectorAll("#bookEdit>label>input").forEach((e) => { - e.value = TheBook[e.id.replaceAll("edit_", "")]; - }) + let isLocked = () => { return TheBook.lock === 1 || TheBook.lock === true; } @@ -2076,116 +2071,6 @@ async function createDetails(TheBook, provider) { } } } - document.getElementById("sendEdit").onclick = async () => { - let values = []; - let columns = []; - document.querySelectorAll("#commonEdit>label>input").forEach((e) => { - values.push(e.value.replaceAll("'", "''").replaceAll('"', "'")); - columns.push(e.id.replaceAll("edit_", "")) - }) - document.querySelectorAll("#bookEdit>label>input").forEach((e) => { - values.push(e.value.replaceAll("'", "''").replaceAll('"', "'")) - columns.push(e.id.replaceAll("edit_", "")) - }) - values.push(document.getElementById("lockCheck").checked); - console.log(values); - - columns.push("lock"); - await fetch(PDP + "/DB/update", { - method: "POST", headers: { - "Content-Type": "application/json" - }, body: JSON.stringify({ - "token": currentProfile.getToken, - "table": "Books", - "type": "edit", - "column": columns, - "whereEl": TheBook.PATH, - "value": values, - "where": "PATH" - }, null, 2) - }) - } - if (TheBook.characters !== "null" && providerEnum.Marvel) { - document.getElementById("id").innerText = language["thisisa"] + TheBook.format + " " + language["of"] + " " + TheBook.pageCount + " " + language["pages"] + "
" + language["Thisispartofthe"] + JSON.parse(TheBook.series).name + "' " + language["series"]; - } else { - if (provider === providerEnum.Anilist) { - document.getElementById("id").innerText = language["Thisispartofthe"] + TheBook.series.split("_")[2].replaceAll("$", " ") + "' series."; - } else if (provider === providerEnum.Marvel) { - document.getElementById("id").innerText = language["Thisispartofthe"] + JSON.parse(TheBook.series).name + "' series."; - } else if (provider === providerEnum.MANUAL) { - document.getElementById("id").innerText = language["Thisispartofthe"] + TheBook.series + "' series."; - } else if (provider === providerEnum.OL) { - document.getElementById("id").innerText = language["Thisispartofthe"] + TheBook.series + "' series."; - } else if (provider === providerEnum.GBooks) { - document.getElementById("id").innerText = language["this is a"] + TheBook.format + " " + language["of"] + " " + TheBook.pageCount + " " + language["pages"] + "
" + language["Thisispartofthe"] + TheBook.series + "' " + language["series"]; - - } - } - - document.getElementById("checkbtn").addEventListener("click", function (e) { - AllForOne("unread", "reading", "read", TheBook.ID_book); - Toastifycation(language["mkread"], "#00C33C"); - }); - document.getElementById("readingbtndetails").addEventListener("click", function (e) { - AllForOne("unread", "read", "reading", TheBook.ID_book); - Toastifycation(language["mkreading"], "#00C33C"); - }); - document.getElementById("decheckbtn").addEventListener("click", function (e) { - AllForOne("read", "reading", "unread", TheBook.ID_book); - Toastifycation(language["mkunread"], "#00C33C"); - }); - - document.getElementById("favoritebtn").addEventListener("click", async function (e) { - if (TheBook.favorite === 1) { - TheBook.favorite = 0; - Toastifycation(language["remove_fav"], "#00C33C"); - await getFromDB("Books", "* FROM Books WHERE favorite=1").then(async (resa) => { - let bookList = JSON.parse(resa); - console.log(bookList); - for (let i = 0; i < bookList.length; i++) { - if (bookList[i].PATH.toLowerCase().includes(TheBook.NOM.toLowerCase().replaceAll('"', ''))) { - let options = { - method: "POST", headers: { - "Content-Type": "application/json" - }, body: JSON.stringify({ - "token": currentProfile.getToken, - "table": "Books", - "column": "favorite", - "whereEl": bookList[i].PATH, - "value": false, - "where": "PATH" - }, null, 2) - }; - await fetch(PDP + "/DB/update", options); - } - } - }); - } else { - TheBook.favorite = 1; - Toastifycation(language["add_fav"], "#00C33C"); - await getFromDB("Books", "* FROM Books WHERE favorite=0").then(async (resa) => { - let bookList = JSON.parse(resa); - console.log(bookList); - for (let i = 0; i < bookList.length; i++) { - if (bookList[i].PATH.toLowerCase().includes(TheBook.NOM.toLowerCase().replaceAll('"', ''))) { - let options = { - method: "POST", headers: { - "Content-Type": "application/json" - }, body: JSON.stringify({ - "token": currentProfile.getToken, - "table": "Books", - "column": "favorite", - "whereEl": bookList[i].PATH, - "value": true, - "where": "PATH" - }, null, 2) - }; - await fetch(PDP + "/DB/update", options); - } - } - }); - } - }); if (TheBook.characters !== "null") { let NameToFetchList = []; if (provider === providerEnum.Marvel) { @@ -2249,39 +2134,6 @@ async function createDetails(TheBook, provider) { container.appendChild(divs); }); }); - if (TheBook.read === 1 || TheBook.read === "true") { - document.getElementById("Status").innerText = language["READ"]; - document.getElementById("Status").className = "released"; - } else if (TheBook.unread === 1 || TheBook.unread === "true") { - document.getElementById("Status").innerText = language["UNREAD"]; - document.getElementById("Status").className = "NotYet"; - } else if (TheBook.reading === 1 || TheBook.reading === "true") { - document.getElementById("Status").innerText = language["READING"]; - document.getElementById("Status").className = "releasing"; - } - if (TheBook.favorite === 1) { - document.getElementById("Status").innerText += language["favoriteParenthesis"]; - } - document.getElementById("readstat").innerHTML = "" + " / " + TheBook.pageCount + " " + language["pagesRead"]; - document.getElementById("readAddInput").value = TheBook.last_page; - document.getElementById("readAddInput").max = TheBook.pageCount; - document.getElementById("readAddInput").addEventListener("change", async function (e) { - let options = { - method: "POST", headers: { - "Content-Type": "application/json" - }, body: JSON.stringify({ - "token": currentProfile.getToken, - "table": "Books", - "column": "last_page", - "whereEl": TheBook.ID_book, - "value": e.target.value, - "where": "ID_book" - }, null, 2) - }; - await fetch(PDP + "/DB/update", options).catch((err) => { - Toastifycation("Error", "#d92027"); - }); - }); document.getElementById("characters").innerHTML = "

" + language["characters"] + ":

" + language["Numberofcharacters"] + ((provider === providerEnum.Marvel) ? (JSON.parse(TheBook.characters)["available"]) : ((TheBook.characters !== "null") ? (JSON.parse(TheBook.characters).length) : (0))) + "
"; document.getElementById("detailSeparator").style.marginTop = "5vh"; let scrollCharactersAmount = 0; @@ -2402,33 +2254,6 @@ async function createDetails(TheBook, provider) { document.getElementById("Staff").appendChild(moveRight2); document.getElementById("Staff").appendChild(container2); } - if (TheBook.collectedIssues !== "null") { - for (let a = 0; a < JSON.parse(TheBook.collectedIssues).length; a++) { - document.getElementById("colissue").innerHTML += JSON.parse(TheBook.collectedIssues)[a].name + "
"; - } - } - if (TheBook.collections !== "null") { - for (let a = 0; a < JSON.parse(TheBook.collections).length; a++) { - document.getElementById("col").innerHTML += JSON.parse(TheBook.collections)[a].name + "
"; - } - } - if (TheBook.issueNumber !== "null" && TheBook.issueNumber !== "" && TheBook.issueNumber != null) { - document.getElementById("chapters").innerText = language["Numberofthisvolumewithintheseries"] + TheBook.issueNumber; - } else { - document.getElementById("chapters").innerText = ""; - } - if (TheBook.dates !== "null") { - document.getElementById("startDate").innerHTML = language["dates"] + "
"; - try { - - for (let b = 0; b < JSON.parse(TheBook.dates).length; b++) { - document.getElementById("startDate").innerHTML += JSON.parse(TheBook.dates)[b].type.replace(/([A-Z])/g, ' $1').trim() + " : " + convertDate(JSON.parse(TheBook.dates)[b].date) + "
"; - } - } catch (e) { - document.getElementById("startDate").innerHTML += TheBook.dates + "
"; - - } - } if (TheBook.variants !== "null" && TheBook.variants !== "" && TheBook.variants != null) { if (provider === providerEnum.Marvel) { createVariants(TheBook);