2023-09-20 14:16:47 +02:00
|
|
|
|
let monitoringJobsCount = 0;
|
|
|
|
|
let runningJobs = [];
|
2023-09-08 19:59:12 +02:00
|
|
|
|
let waitingJobs = [];
|
2023-08-31 16:45:33 +02:00
|
|
|
|
let notificationConnectorTypes = [];
|
|
|
|
|
let libraryConnectorTypes = [];
|
2023-09-01 23:43:41 +02:00
|
|
|
|
let selectedManga;
|
2023-09-02 14:14:18 +02:00
|
|
|
|
let selectedJob;
|
2023-08-31 16:45:33 +02:00
|
|
|
|
|
2023-05-31 22:16:14 +02:00
|
|
|
|
const searchBox = document.querySelector("#searchbox");
|
2023-05-25 15:34:10 +02:00
|
|
|
|
const settingsPopup = document.querySelector("#settingsPopup");
|
2023-05-23 16:27:09 +02:00
|
|
|
|
const settingsCog = document.querySelector("#settingscog");
|
|
|
|
|
const tasksContent = document.querySelector("content");
|
2023-09-02 14:14:18 +02:00
|
|
|
|
const createMonitorTaskButton = document.querySelector("#createMonitoJobButton");
|
|
|
|
|
const createDownloadChapterTaskButton = document.querySelector("#createDownloadChapterJobButton");
|
|
|
|
|
const startJobButton = document.querySelector("#startJobButton");
|
2023-09-02 15:05:45 +02:00
|
|
|
|
const cancelJobButton = document.querySelector("#cancelJobButton");
|
2023-09-02 14:14:18 +02:00
|
|
|
|
const deleteJobButton = document.querySelector("#deleteJobButton");
|
2023-09-01 23:43:41 +02:00
|
|
|
|
const mangaViewerPopup = document.querySelector("#publicationViewerPopup");
|
|
|
|
|
const mangaViewerWindow = document.querySelector("publication-viewer");
|
|
|
|
|
const mangaViewerDescription = document.querySelector("#publicationViewerDescription");
|
|
|
|
|
const mangaViewerName = document.querySelector("#publicationViewerName");
|
|
|
|
|
const mangaViewerTags = document.querySelector("#publicationViewerTags");
|
|
|
|
|
const mangaViewerAuthor = document.querySelector("#publicationViewerAuthor");
|
|
|
|
|
const mangaViewCover = document.querySelector("#pubviewcover");
|
2023-05-24 20:57:17 +02:00
|
|
|
|
const settingDownloadLocation = document.querySelector("#downloadLocation");
|
2023-05-24 21:48:54 +02:00
|
|
|
|
const settingKomgaUrl = document.querySelector("#komgaUrl");
|
2023-05-24 20:57:17 +02:00
|
|
|
|
const settingKomgaUser = document.querySelector("#komgaUsername");
|
|
|
|
|
const settingKomgaPass = document.querySelector("#komgaPassword");
|
2023-06-03 16:25:04 +02:00
|
|
|
|
const settingKavitaUrl = document.querySelector("#kavitaUrl");
|
2023-06-03 21:26:29 +02:00
|
|
|
|
const settingKavitaUser = document.querySelector("#kavitaUsername");
|
|
|
|
|
const settingKavitaPass = document.querySelector("#kavitaPassword");
|
2023-06-15 18:38:47 +02:00
|
|
|
|
const settingGotifyUrl = document.querySelector("#gotifyUrl");
|
|
|
|
|
const settingGotifyAppToken = document.querySelector("#gotifyAppToken");
|
2023-06-15 18:57:21 +02:00
|
|
|
|
const settingLunaseaWebhook = document.querySelector("#lunaseaWebhook");
|
2023-10-27 13:55:42 +02:00
|
|
|
|
const settingNtfyEndpoint = document.querySelector("#ntfyEndpoint");
|
|
|
|
|
const settingNtfyAuth = document.querySelector("#ntfyAuth");
|
2023-05-24 21:48:54 +02:00
|
|
|
|
const settingKomgaConfigured = document.querySelector("#komgaConfigured");
|
2023-06-03 16:25:04 +02:00
|
|
|
|
const settingKavitaConfigured = document.querySelector("#kavitaConfigured");
|
2023-06-15 18:38:47 +02:00
|
|
|
|
const settingGotifyConfigured = document.querySelector("#gotifyConfigured");
|
2023-06-15 18:57:21 +02:00
|
|
|
|
const settingLunaseaConfigured = document.querySelector("#lunaseaConfigured");
|
2023-10-27 13:55:42 +02:00
|
|
|
|
const settingNtfyConfigured = document.querySelector("#ntfyConfigured");
|
2023-05-25 10:42:19 +02:00
|
|
|
|
const settingApiUri = document.querySelector("#settingApiUri");
|
2023-10-27 05:23:08 +02:00
|
|
|
|
const settingMangaHoverCheckbox = document.querySelector("#mangaHoverCheckbox");
|
2023-08-31 23:45:13 +02:00
|
|
|
|
const newMangaPopup = document.querySelector("#newMangaPopup");
|
|
|
|
|
const newMangaConnector = document.querySelector("#newMangaConnector");
|
|
|
|
|
const newMangaTitle = document.querySelector("#newMangaTitle");
|
|
|
|
|
const newMangaResult = document.querySelector("#newMangaResult");
|
2023-09-13 14:30:13 +02:00
|
|
|
|
const newMangaTranslatedLanguage = document.querySelector("#newMangaTranslatedLanguage");
|
2023-09-02 16:16:29 +02:00
|
|
|
|
const jobsRunningTag = document.querySelector("#jobsRunningTag");
|
|
|
|
|
const jobsQueuedTag = document.querySelector("#jobsQueuedTag");
|
2023-09-08 16:32:48 +02:00
|
|
|
|
const loaderdiv = document.querySelector('#loaderdiv');
|
2023-09-08 19:59:12 +02:00
|
|
|
|
const jobStatusView = document.querySelector("#jobStatusView");
|
|
|
|
|
const jobStatusRunning = document.querySelector("#jobStatusRunning");
|
|
|
|
|
const jobStatusWaiting = document.querySelector("#jobStatusWaiting");
|
2023-08-31 23:45:13 +02:00
|
|
|
|
|
|
|
|
|
function Setup(){
|
2023-09-08 16:32:48 +02:00
|
|
|
|
Ping().then((ret) => {
|
|
|
|
|
loaderdiv.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
GetAvailableNotificationConnectors().then((json) => {
|
|
|
|
|
json.forEach(connector => {
|
|
|
|
|
notificationConnectorTypes[connector.Key] = connector.Value;
|
|
|
|
|
});
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
|
|
|
|
|
2023-09-08 16:32:48 +02:00
|
|
|
|
GetAvailableLibraryConnectors().then((json) => {
|
|
|
|
|
json.forEach(connector => {
|
|
|
|
|
libraryConnectorTypes[connector.Key] = connector.Value;
|
|
|
|
|
});
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
2023-09-08 16:32:48 +02:00
|
|
|
|
|
|
|
|
|
GetAvailableControllers().then((json) => {
|
2023-09-20 14:30:22 +02:00
|
|
|
|
newMangaConnector.replaceChildren();
|
|
|
|
|
json.forEach(connector => {
|
2023-09-08 16:32:48 +02:00
|
|
|
|
var option = document.createElement('option');
|
|
|
|
|
option.value = connector;
|
|
|
|
|
option.innerText = connector;
|
|
|
|
|
newMangaConnector.appendChild(option);
|
|
|
|
|
});
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
|
|
|
|
|
2023-09-26 18:09:45 +02:00
|
|
|
|
ResetContent();
|
2023-09-08 16:32:48 +02:00
|
|
|
|
UpdateJobs();
|
2023-10-27 16:48:08 +02:00
|
|
|
|
GetSettings().then((json) => {
|
2023-10-30 03:24:16 +01:00
|
|
|
|
//console.log(json);
|
2023-10-27 16:48:08 +02:00
|
|
|
|
settingDownloadLocation.innerText = json.downloadLocation;
|
|
|
|
|
settingApiUri.placeholder = apiUri;
|
2023-10-30 03:24:16 +01:00
|
|
|
|
//console.log(json.styleSheet);
|
2023-10-27 17:18:37 +02:00
|
|
|
|
if (json.styleSheet == 'hover') {
|
2023-10-27 16:48:08 +02:00
|
|
|
|
settingMangaHoverCheckbox.checked = true;
|
|
|
|
|
document.getElementById('pagestyle').setAttribute('href', 'styles/style_mangahover.css');
|
2023-10-27 17:18:37 +02:00
|
|
|
|
} else {
|
|
|
|
|
settingMangaHoverCheckbox.checked = false;
|
|
|
|
|
document.getElementById('pagestyle').setAttribute('href', 'styles/style_default.css');
|
2023-10-27 16:48:08 +02:00
|
|
|
|
}
|
|
|
|
|
});
|
2023-09-08 16:32:48 +02:00
|
|
|
|
setInterval(() => {
|
|
|
|
|
UpdateJobs();
|
|
|
|
|
}, 1000);
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Setup();
|
2023-05-24 20:57:41 +02:00
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
function ResetContent(){
|
|
|
|
|
//Delete everything
|
|
|
|
|
tasksContent.replaceChildren();
|
|
|
|
|
|
|
|
|
|
//Add "Add new Task" Button
|
|
|
|
|
var add = document.createElement("div");
|
|
|
|
|
add.setAttribute("id", "addPublication")
|
|
|
|
|
var plus = document.createElement("p");
|
|
|
|
|
plus.innerText = "+";
|
|
|
|
|
add.appendChild(plus);
|
2023-08-31 23:45:13 +02:00
|
|
|
|
add.addEventListener("click", () => ShowNewMangaSearch());
|
2023-08-31 16:45:33 +02:00
|
|
|
|
tasksContent.appendChild(add);
|
2023-10-30 18:29:39 +01:00
|
|
|
|
|
|
|
|
|
//Populate with the monitored mangas
|
|
|
|
|
GetMonitorJobs().then((json) => {
|
|
|
|
|
//console.log(json);
|
|
|
|
|
json.forEach(job => {
|
|
|
|
|
var mangaView = CreateManga(job.manga, job.mangaConnector.name);
|
|
|
|
|
mangaView.addEventListener("click", (event) => {
|
|
|
|
|
ShowMangaWindow(job, job.manga, event, false);
|
|
|
|
|
});
|
|
|
|
|
tasksContent.appendChild(mangaView);
|
|
|
|
|
});
|
|
|
|
|
monitoringJobsCount = json.length;
|
|
|
|
|
});
|
2023-05-24 20:57:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 23:45:13 +02:00
|
|
|
|
function ShowNewMangaSearch(){
|
|
|
|
|
newMangaTitle.value = "";
|
|
|
|
|
newMangaPopup.style.display = "block";
|
|
|
|
|
newMangaResult.replaceChildren();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newMangaTitle.addEventListener("keypress", (event) => { if(event.key === "Enter") GetNewMangaItems();})
|
|
|
|
|
function GetNewMangaItems(){
|
|
|
|
|
if(newMangaTitle.value.length < 4)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-09-01 23:43:41 +02:00
|
|
|
|
newMangaResult.replaceChildren();
|
2023-08-31 23:45:13 +02:00
|
|
|
|
newMangaConnector.disabled = true;
|
|
|
|
|
newMangaTitle.disabled = true;
|
2023-09-13 14:30:13 +02:00
|
|
|
|
newMangaTranslatedLanguage.disabled = true;
|
2023-08-31 23:45:13 +02:00
|
|
|
|
GetPublicationFromConnector(newMangaConnector.value, newMangaTitle.value).then((json) => {
|
2023-09-01 23:43:41 +02:00
|
|
|
|
//console.log(json);
|
2023-08-31 23:45:13 +02:00
|
|
|
|
if(json.length > 0)
|
|
|
|
|
newMangaResult.style.display = "flex";
|
|
|
|
|
json.forEach(result => {
|
2023-09-01 23:43:41 +02:00
|
|
|
|
var mangaElement = CreateManga(result, newMangaConnector.value)
|
|
|
|
|
newMangaResult.appendChild(mangaElement);
|
|
|
|
|
mangaElement.addEventListener("click", (event) => {
|
2023-09-02 14:14:18 +02:00
|
|
|
|
ShowMangaWindow(null, result, event, true);
|
2023-09-01 23:43:41 +02:00
|
|
|
|
});
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
newMangaConnector.disabled = false;
|
|
|
|
|
newMangaTitle.disabled = false;
|
2023-09-13 14:30:13 +02:00
|
|
|
|
newMangaTranslatedLanguage.disabled = false;
|
2023-08-31 23:45:13 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
//Returns a new "Publication" Item to display in the jobs section
|
2023-09-01 23:43:41 +02:00
|
|
|
|
function CreateManga(manga, connector){
|
2023-11-02 00:06:47 +01:00
|
|
|
|
//Create a new publication and set an internal ID
|
2023-09-01 23:43:41 +02:00
|
|
|
|
var mangaElement = document.createElement('publication');
|
2023-09-08 19:59:12 +02:00
|
|
|
|
mangaElement.id = GetValidSelector(manga.internalId);
|
2023-11-02 00:06:47 +01:00
|
|
|
|
|
|
|
|
|
//Append the cover image to the publication
|
2023-09-01 23:43:41 +02:00
|
|
|
|
var mangaImage = document.createElement('img');
|
|
|
|
|
mangaImage.src = GetCoverUrl(manga.internalId);
|
|
|
|
|
mangaElement.appendChild(mangaImage);
|
2023-11-02 00:06:47 +01:00
|
|
|
|
|
|
|
|
|
//Append the publication information to the publication
|
2023-11-02 01:01:28 +01:00
|
|
|
|
//console.log(manga);
|
2023-05-23 15:15:29 +02:00
|
|
|
|
var info = document.createElement('publication-information');
|
|
|
|
|
var connectorName = document.createElement('connector-name');
|
2023-05-23 16:27:09 +02:00
|
|
|
|
connectorName.innerText = connector;
|
2023-05-23 15:15:29 +02:00
|
|
|
|
connectorName.className = "pill";
|
2023-09-20 14:30:22 +02:00
|
|
|
|
connectorName.style.backgroundColor = stringToColour(connector);
|
2023-05-23 15:15:29 +02:00
|
|
|
|
info.appendChild(connectorName);
|
2023-11-02 00:06:47 +01:00
|
|
|
|
|
2023-09-01 23:43:41 +02:00
|
|
|
|
var mangaName = document.createElement('publication-name');
|
|
|
|
|
mangaName.innerText = manga.sortName;
|
2023-11-02 00:06:47 +01:00
|
|
|
|
|
|
|
|
|
//Create the publication status indicator
|
|
|
|
|
var releaseStatus = document.createElement('publication-status');
|
|
|
|
|
var statusTooltip = document.createElement('status-tooltip');
|
|
|
|
|
if (manga.releaseStatus == 0) {
|
|
|
|
|
releaseStatus.style.backgroundColor = 'limegreen';
|
|
|
|
|
statusTooltip.innerText = "Ongoing"
|
|
|
|
|
}else if(manga.releaseStatus == 1){
|
|
|
|
|
releaseStatus.style.backgroundColor = 'blueviolet';
|
|
|
|
|
statusTooltip.innerText = "Completed"
|
|
|
|
|
} else if (manga.releaseStatus == 2) {
|
|
|
|
|
releaseStatus.style.backgroundColor = 'darkorange';
|
|
|
|
|
statusTooltip.innerText = "On Hiatus"
|
|
|
|
|
} else if (manga.releaseStatus == 3) {
|
|
|
|
|
releaseStatus.style.backgroundColor = 'firebrick';
|
|
|
|
|
statusTooltip.innerText = "Cancelled"
|
|
|
|
|
} else if (manga.releaseStatus == 4) {
|
|
|
|
|
releaseStatus.style.backgroundColor = 'aqua';
|
|
|
|
|
statusTooltip.innerText = "Upcoming";
|
|
|
|
|
} else {
|
|
|
|
|
releaseStatus.style.backgroundColor = 'gray';
|
|
|
|
|
statusTooltip.innerText = 'Status Unavailable';
|
|
|
|
|
}
|
|
|
|
|
releaseStatus.appendChild(statusTooltip); //Append the tooltip to the indicator circle
|
|
|
|
|
mangaName.appendChild(releaseStatus); //Append the release status indicator to the info block
|
|
|
|
|
|
2023-09-01 23:43:41 +02:00
|
|
|
|
info.appendChild(mangaName);
|
|
|
|
|
mangaElement.appendChild(info);
|
|
|
|
|
return mangaElement;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-02 14:14:18 +02:00
|
|
|
|
createMonitorJobButton.addEventListener("click", () => {
|
2023-09-13 14:30:13 +02:00
|
|
|
|
CreateMonitorJob(newMangaConnector.value, selectedManga.internalId, newMangaTranslatedLanguage.value);
|
2023-09-02 14:14:18 +02:00
|
|
|
|
UpdateJobs();
|
2023-09-01 23:43:41 +02:00
|
|
|
|
mangaViewerPopup.style.display = "none";
|
2023-10-30 18:29:39 +01:00
|
|
|
|
ResetContent();
|
2023-09-01 23:43:41 +02:00
|
|
|
|
});
|
2023-09-02 14:14:18 +02:00
|
|
|
|
startJobButton.addEventListener("click", () => {
|
|
|
|
|
StartJob(selectedJob.id);
|
|
|
|
|
mangaViewerPopup.style.display = "none";
|
|
|
|
|
});
|
2023-09-02 15:05:45 +02:00
|
|
|
|
cancelJobButton.addEventListener("click", () => {
|
|
|
|
|
CancelJob(selectedJob.id);
|
|
|
|
|
mangaViewerPopup.style.display = "none";
|
|
|
|
|
});
|
2023-09-02 14:14:18 +02:00
|
|
|
|
deleteJobButton.addEventListener("click", () => {
|
|
|
|
|
RemoveJob(selectedJob.id);
|
2023-09-01 23:43:41 +02:00
|
|
|
|
UpdateJobs();
|
2023-09-02 14:14:18 +02:00
|
|
|
|
mangaViewerPopup.style.display = "none";
|
2023-10-30 18:29:39 +01:00
|
|
|
|
ResetContent();
|
2023-09-02 14:14:18 +02:00
|
|
|
|
});
|
2023-05-23 15:15:29 +02:00
|
|
|
|
|
2023-09-02 14:14:18 +02:00
|
|
|
|
function ShowMangaWindow(job, manga, event, add){
|
2023-09-01 23:43:41 +02:00
|
|
|
|
selectedManga = manga;
|
2023-09-02 14:14:18 +02:00
|
|
|
|
selectedJob = job;
|
2023-05-25 16:05:54 +02:00
|
|
|
|
//Show popup
|
2023-09-01 23:43:41 +02:00
|
|
|
|
mangaViewerPopup.style.display = "block";
|
2023-05-25 16:05:54 +02:00
|
|
|
|
|
2023-05-24 20:17:50 +02:00
|
|
|
|
//Set position to mouse-position
|
2023-09-01 23:43:41 +02:00
|
|
|
|
if(event.clientY < window.innerHeight - mangaViewerWindow.offsetHeight)
|
|
|
|
|
mangaViewerWindow.style.top = `${event.clientY}px`;
|
2023-05-25 16:05:54 +02:00
|
|
|
|
else
|
2023-09-01 23:43:41 +02:00
|
|
|
|
mangaViewerWindow.style.top = `${event.clientY - mangaViewerWindow.offsetHeight}px`;
|
2023-05-25 16:05:54 +02:00
|
|
|
|
|
2023-09-01 23:43:41 +02:00
|
|
|
|
if(event.clientX < window.innerWidth - mangaViewerWindow.offsetWidth)
|
|
|
|
|
mangaViewerWindow.style.left = `${event.clientX}px`;
|
2023-05-25 16:05:54 +02:00
|
|
|
|
else
|
2023-09-01 23:43:41 +02:00
|
|
|
|
mangaViewerWindow.style.left = `${event.clientX - mangaViewerWindow.offsetWidth}px`;
|
2023-05-23 17:57:48 +02:00
|
|
|
|
|
2023-05-24 20:17:50 +02:00
|
|
|
|
//Edit information inside the window
|
2023-09-01 23:43:41 +02:00
|
|
|
|
mangaViewerName.innerText = manga.sortName;
|
|
|
|
|
mangaViewerTags.innerText = manga.tags.join(", ");
|
|
|
|
|
mangaViewerDescription.innerText = manga.description;
|
|
|
|
|
mangaViewerAuthor.innerText = manga.authors.join(',');
|
|
|
|
|
mangaViewCover.src = GetCoverUrl(manga.internalId);
|
|
|
|
|
toEditId = manga.internalId;
|
2023-05-23 17:57:48 +02:00
|
|
|
|
|
2023-05-24 20:17:50 +02:00
|
|
|
|
//Check what action should be listed
|
2023-05-23 18:28:27 +02:00
|
|
|
|
if(add){
|
2023-09-02 14:14:18 +02:00
|
|
|
|
createMonitorJobButton.style.display = "initial";
|
2023-09-02 22:15:48 +02:00
|
|
|
|
createDownloadChapterJobButton.style.display = "none";
|
2023-09-02 15:05:45 +02:00
|
|
|
|
cancelJobButton.style.display = "none";
|
2023-09-02 14:14:18 +02:00
|
|
|
|
startJobButton.style.display = "none";
|
|
|
|
|
deleteJobButton.style.display = "none";
|
2023-05-23 18:28:27 +02:00
|
|
|
|
}
|
2023-05-23 18:46:06 +02:00
|
|
|
|
else{
|
2023-09-02 14:14:18 +02:00
|
|
|
|
createMonitorJobButton.style.display = "none";
|
|
|
|
|
createDownloadChapterJobButton.style.display = "none";
|
2023-09-02 15:05:45 +02:00
|
|
|
|
cancelJobButton.style.display = "initial";
|
2023-09-02 14:14:18 +02:00
|
|
|
|
startJobButton.style.display = "initial";
|
|
|
|
|
deleteJobButton.style.display = "initial";
|
2023-05-23 18:46:06 +02:00
|
|
|
|
}
|
2023-05-23 17:57:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-24 20:17:50 +02:00
|
|
|
|
function HidePublicationPopup(){
|
|
|
|
|
publicationViewerPopup.style.display = "none";
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
searchBox.addEventListener("keyup", () => FilterResults());
|
|
|
|
|
//Filter shown jobs
|
2023-05-31 22:16:14 +02:00
|
|
|
|
function FilterResults(){
|
|
|
|
|
if(searchBox.value.length > 0){
|
|
|
|
|
tasksContent.childNodes.forEach(publication => {
|
|
|
|
|
publication.childNodes.forEach(item => {
|
|
|
|
|
if(item.nodeName.toLowerCase() == "publication-information"){
|
|
|
|
|
item.childNodes.forEach(information => {
|
|
|
|
|
if(information.nodeName.toLowerCase() == "publication-name"){
|
|
|
|
|
if(!information.textContent.toLowerCase().includes(searchBox.value.toLowerCase())){
|
|
|
|
|
publication.style.display = "none";
|
|
|
|
|
}else{
|
|
|
|
|
publication.style.display = "initial";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}else{
|
|
|
|
|
tasksContent.childNodes.forEach(publication => publication.style.display = "initial");
|
|
|
|
|
}
|
2023-06-09 23:46:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
settingsCog.addEventListener("click", () => {
|
|
|
|
|
OpenSettings();
|
|
|
|
|
settingsPopup.style.display = "flex";
|
|
|
|
|
});
|
2023-06-09 23:58:04 +02:00
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
settingKomgaUrl.addEventListener("keypress", (event) => { { if(event.key === "Enter") UpdateSettings(); } });
|
|
|
|
|
settingKomgaUser.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingKomgaPass.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingKavitaUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingKavitaUser.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingKavitaPass.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingGotifyUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingGotifyAppToken.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingLunaseaWebhook.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
2023-10-27 13:55:42 +02:00
|
|
|
|
settingNtfyEndpoint.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
|
|
|
|
settingNtfyAuth.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
2023-08-31 16:45:33 +02:00
|
|
|
|
settingApiUri.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
2023-06-09 23:46:10 +02:00
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
function OpenSettings(){
|
|
|
|
|
settingGotifyConfigured.innerText = "❌";
|
|
|
|
|
settingLunaseaConfigured.innerText = "❌";
|
2023-10-27 14:08:31 +02:00
|
|
|
|
settingNtfyConfigured.innerText = "❌";
|
2023-08-31 16:45:33 +02:00
|
|
|
|
settingKavitaConfigured.innerText = "❌";
|
|
|
|
|
settingKomgaConfigured.innerText = "❌";
|
|
|
|
|
settingKomgaUrl.value = "";
|
|
|
|
|
settingKomgaUser.value = "";
|
|
|
|
|
settingKomgaPass.value = "";
|
|
|
|
|
settingKavitaUrl.value = "";
|
|
|
|
|
settingKavitaUser.value = "";
|
|
|
|
|
settingKavitaPass.value = "";
|
|
|
|
|
settingGotifyUrl.value = "";
|
|
|
|
|
settingGotifyAppToken.value = "";
|
|
|
|
|
settingLunaseaWebhook.value = "";
|
2023-10-27 13:55:42 +02:00
|
|
|
|
settingNtfyAuth.value = "";
|
|
|
|
|
settingNtfyEndpoint.value = "";
|
2023-08-31 16:45:33 +02:00
|
|
|
|
settingApiUri.value = "";
|
2023-10-27 05:23:08 +02:00
|
|
|
|
settingMangaHoverCheckbox.checked = false;
|
2023-08-31 16:45:33 +02:00
|
|
|
|
|
|
|
|
|
GetSettings().then((json) => {
|
|
|
|
|
//console.log(json);
|
|
|
|
|
settingDownloadLocation.innerText = json.downloadLocation;
|
|
|
|
|
settingApiUri.placeholder = apiUri;
|
2023-10-30 03:24:16 +01:00
|
|
|
|
//console.log(json.styleSheet);
|
2023-10-27 17:18:37 +02:00
|
|
|
|
if (json.styleSheet == 'hover') {
|
2023-10-27 05:23:08 +02:00
|
|
|
|
settingMangaHoverCheckbox.checked = true;
|
|
|
|
|
document.getElementById('pagestyle').setAttribute('href', 'styles/style_mangahover.css');
|
2023-10-27 17:18:37 +02:00
|
|
|
|
} else {
|
|
|
|
|
settingMangaHoverCheckbox.checked = false;
|
|
|
|
|
document.getElementById('pagestyle').setAttribute('href', 'styles/style_default.css');
|
2023-10-27 05:23:08 +02:00
|
|
|
|
}
|
2023-08-31 16:45:33 +02:00
|
|
|
|
});
|
|
|
|
|
GetLibraryConnectors().then((json) => {
|
|
|
|
|
//console.log(json);
|
|
|
|
|
json.forEach(connector => {
|
|
|
|
|
switch(libraryConnectorTypes[connector.libraryType]){
|
|
|
|
|
case "Kavita":
|
|
|
|
|
settingKavitaConfigured.innerText = "✅";
|
|
|
|
|
settingKavitaUrl.placeholder = connector.baseUrl;
|
|
|
|
|
settingKavitaUser.placeholder = "***";
|
|
|
|
|
settingKavitaPass.placeholder = "***";
|
|
|
|
|
break;
|
|
|
|
|
case "Komga":
|
|
|
|
|
settingKomgaConfigured.innerText = "✅";
|
|
|
|
|
settingKomgaUrl.placeholder = connector.baseUrl;
|
|
|
|
|
settingKomgaUser.placeholder = "***";
|
|
|
|
|
settingKomgaPass.placeholder = "***";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.log("Unknown type");
|
|
|
|
|
console.log(connector);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
GetNotificationConnectors().then((json) => {
|
|
|
|
|
//console.log(json);
|
|
|
|
|
json.forEach(connector => {
|
|
|
|
|
switch(notificationConnectorTypes[connector.notificationConnectorType]){
|
|
|
|
|
case "Gotify":
|
|
|
|
|
settingGotifyUrl.placeholder = connector.endpoint;
|
|
|
|
|
settingGotifyAppToken.placeholder = "***";
|
|
|
|
|
settingGotifyConfigured.innerText = "✅";
|
|
|
|
|
break;
|
|
|
|
|
case "LunaSea":
|
|
|
|
|
settingLunaseaConfigured.innerText = "✅";
|
|
|
|
|
settingLunaseaWebhook.placeholder = connector.id;
|
|
|
|
|
break;
|
2023-10-27 13:55:42 +02:00
|
|
|
|
case "Ntfy":
|
|
|
|
|
settingNtfyConfigured.innerText = "✅";
|
|
|
|
|
settingNtfyEndpoint.placeholder = connector.endpoint;
|
|
|
|
|
settingNtfyAuth.placeholder = "***";
|
|
|
|
|
break;
|
2023-08-31 16:45:33 +02:00
|
|
|
|
default:
|
|
|
|
|
console.log("Unknown type");
|
|
|
|
|
console.log(connector);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2023-06-09 23:46:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
function UpdateSettings(){
|
|
|
|
|
if(settingApiUri.value != ""){
|
|
|
|
|
apiUri = settingApiUri.value;
|
|
|
|
|
setCookie("apiUri", apiUri);
|
|
|
|
|
Setup();
|
|
|
|
|
}
|
2023-10-27 05:23:08 +02:00
|
|
|
|
|
|
|
|
|
// If the checkbox is checked, set the style to style_mangahover.css and
|
|
|
|
|
if (document.getElementById("mangaHoverCheckbox").checked == true){
|
|
|
|
|
ChangeStyleSheet('hover')
|
2023-10-30 03:24:16 +01:00
|
|
|
|
//console.log('Changing theme to mangahover')
|
2023-10-27 05:23:08 +02:00
|
|
|
|
} else {
|
|
|
|
|
ChangeStyleSheet('default');
|
2023-10-30 03:24:16 +01:00
|
|
|
|
//console.log('Changing theme to default')
|
2023-10-27 05:23:08 +02:00
|
|
|
|
}
|
2023-08-31 16:45:33 +02:00
|
|
|
|
|
|
|
|
|
if(settingKomgaUrl.value != "" &&
|
|
|
|
|
settingKomgaUser.value != "" &&
|
|
|
|
|
settingKomgaPass.value != ""){
|
|
|
|
|
UpdateKomga(settingKomgaUrl.value, utf8_to_b64(`${settingKomgaUser.value}:${settingKomgaPass.value}`));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(settingKavitaUrl.value != "" &&
|
|
|
|
|
settingKavitaUser.value != "" &&
|
|
|
|
|
settingKavitaPass.value != ""){
|
|
|
|
|
UpdateKavita(settingKavitaUrl.value, settingKavitaUser.value, settingKavitaPass.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(settingGotifyUrl.value != "" &&
|
|
|
|
|
settingGotifyAppToken.value != ""){
|
|
|
|
|
UpdateGotify(settingGotifyUrl.value, settingGotifyAppToken.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(settingLunaseaWebhook.value != ""){
|
|
|
|
|
UpdateLunaSea(settingLunaseaWebhook.value);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 13:55:42 +02:00
|
|
|
|
if(settingNtfyEndpoint.value != "" &&
|
|
|
|
|
settingNtfyAuth.value != ""){
|
|
|
|
|
UpdateNtfy(settingNtfyEndpoint.value, settingNtfyAuth.value);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
OpenSettings();
|
2023-09-08 16:32:48 +02:00
|
|
|
|
Setup();
|
2023-05-31 22:16:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 16:45:33 +02:00
|
|
|
|
function utf8_to_b64(str) {
|
|
|
|
|
return window.btoa(unescape(encodeURIComponent( str )));
|
|
|
|
|
}
|
2023-09-01 23:43:41 +02:00
|
|
|
|
|
|
|
|
|
function UpdateJobs(){
|
2023-10-30 19:09:41 +01:00
|
|
|
|
|
|
|
|
|
GetMonitorJobs().then((json) => {
|
|
|
|
|
if(monitoringJobsCount != json.length){
|
|
|
|
|
ResetContent();
|
|
|
|
|
//console.log(json);
|
|
|
|
|
json.forEach(job => {
|
|
|
|
|
var mangaView = CreateManga(job.manga, job.mangaConnector.name);
|
|
|
|
|
mangaView.addEventListener("click", (event) => {
|
|
|
|
|
ShowMangaWindow(job, job.manga, event, false);
|
|
|
|
|
});
|
|
|
|
|
tasksContent.appendChild(mangaView);
|
|
|
|
|
});
|
|
|
|
|
monitoringJobsCount = json.length;
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-10-30 19:21:22 +01:00
|
|
|
|
|
2023-10-30 18:29:39 +01:00
|
|
|
|
//Get the jobs that are waiting in the queue
|
2023-09-08 19:59:12 +02:00
|
|
|
|
GetWaitingJobs().then((json) => {
|
|
|
|
|
jobsQueuedTag.innerText = json.length;
|
|
|
|
|
|
|
|
|
|
var nowWaitingJobs = [];
|
|
|
|
|
|
|
|
|
|
json.forEach(job => {
|
|
|
|
|
if(!waitingJobs.includes(GetValidSelector(job.id))){
|
|
|
|
|
var jobDom = createJob(job);
|
|
|
|
|
jobStatusWaiting.appendChild(jobDom);
|
|
|
|
|
}
|
|
|
|
|
nowWaitingJobs.push(GetValidSelector(job.id));
|
|
|
|
|
});
|
|
|
|
|
waitingJobs = nowWaitingJobs;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
jobStatusWaiting.childNodes.forEach(child => {
|
|
|
|
|
if(!waitingJobs.includes(child.id))
|
|
|
|
|
jobStatusWaiting.removeChild(child);
|
|
|
|
|
});
|
2023-09-02 16:16:29 +02:00
|
|
|
|
|
2023-10-30 18:29:39 +01:00
|
|
|
|
//Get currently running jobs
|
2023-09-02 16:16:29 +02:00
|
|
|
|
GetRunningJobs().then((json) => {
|
|
|
|
|
jobsRunningTag.innerText = json.length;
|
2023-09-08 19:59:12 +02:00
|
|
|
|
|
|
|
|
|
var nowRunningJobs = [];
|
|
|
|
|
|
|
|
|
|
json.forEach(job => {
|
|
|
|
|
if(!runningJobs.includes(GetValidSelector(job.id))){
|
|
|
|
|
var jobDom = createJob(job);
|
|
|
|
|
jobStatusRunning.appendChild(jobDom);
|
|
|
|
|
}
|
|
|
|
|
nowRunningJobs.push(GetValidSelector(job.id));
|
|
|
|
|
UpdateJobProgress(job.id);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
runningJobs = nowRunningJobs;
|
2023-09-02 16:16:29 +02:00
|
|
|
|
});
|
|
|
|
|
|
2023-09-08 19:59:12 +02:00
|
|
|
|
jobStatusRunning.childNodes.forEach(child => {
|
|
|
|
|
if(!runningJobs.includes(child.id))
|
|
|
|
|
jobStatusRunning.removeChild(child);
|
2023-09-02 16:16:29 +02:00
|
|
|
|
});
|
2023-09-01 23:43:41 +02:00
|
|
|
|
}
|
2023-09-08 19:59:12 +02:00
|
|
|
|
|
|
|
|
|
function createJob(jobjson){
|
|
|
|
|
var manga;
|
|
|
|
|
if(jobjson.chapter != null)
|
|
|
|
|
manga = jobjson.chapter.parentManga;
|
|
|
|
|
else if(jobjson.manga != null)
|
|
|
|
|
manga = jobjson.manga;
|
|
|
|
|
else return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var wrapper = document.createElement("div");
|
|
|
|
|
wrapper.className = "jobWrapper";
|
|
|
|
|
wrapper.id = GetValidSelector(jobjson.id);
|
|
|
|
|
|
|
|
|
|
var image = document.createElement("img");
|
|
|
|
|
image.className = "jobImage";
|
|
|
|
|
image.src = GetCoverUrl(manga.internalId);
|
|
|
|
|
wrapper.appendChild(image);
|
|
|
|
|
|
|
|
|
|
var title = document.createElement("span");
|
|
|
|
|
title.className = "jobTitle";
|
|
|
|
|
if(jobjson.chapter != null)
|
|
|
|
|
title.innerText = `${manga.sortName} - ${jobjson.chapter.fileName}`;
|
|
|
|
|
else if(jobjson.manga != null)
|
|
|
|
|
title.innerText = manga.sortName;
|
|
|
|
|
wrapper.appendChild(title);
|
|
|
|
|
|
|
|
|
|
var progressBar = document.createElement("progress");
|
|
|
|
|
progressBar.className = "jobProgressBar";
|
|
|
|
|
progressBar.id = `jobProgressBar${GetValidSelector(jobjson.id)}`;
|
|
|
|
|
wrapper.appendChild(progressBar);
|
|
|
|
|
|
|
|
|
|
var progressSpan = document.createElement("span");
|
|
|
|
|
progressSpan.className = "jobProgressSpan";
|
|
|
|
|
progressSpan.id = `jobProgressSpan${GetValidSelector(jobjson.id)}`;
|
|
|
|
|
progressSpan.innerText = "0% 00:00:00";
|
|
|
|
|
wrapper.appendChild(progressSpan);
|
|
|
|
|
|
|
|
|
|
var cancelSpan = document.createElement("span");
|
|
|
|
|
cancelSpan.className = "jobCancel";
|
|
|
|
|
cancelSpan.innerText = "Cancel";
|
|
|
|
|
cancelSpan.addEventListener("click", () => CancelJob(jobjson.id));
|
|
|
|
|
wrapper.appendChild(cancelSpan);
|
|
|
|
|
|
|
|
|
|
return wrapper;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ShowJobQueue(){
|
|
|
|
|
jobStatusView.style.display = "initial";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function UpdateJobProgress(jobId){
|
|
|
|
|
GetProgress(jobId).then((json) => {
|
|
|
|
|
var progressBar = document.querySelector(`#jobProgressBar${GetValidSelector(jobId)}`);
|
|
|
|
|
var progressSpan = document.querySelector(`#jobProgressSpan${GetValidSelector(jobId)}`);
|
|
|
|
|
if(progressBar != null && json.progress != 0){
|
|
|
|
|
progressBar.value = json.progress;
|
|
|
|
|
}
|
|
|
|
|
if(progressSpan != null){
|
|
|
|
|
var percentageStr = "0%";
|
|
|
|
|
var timeleftStr = "00:00:00";
|
|
|
|
|
if(json.progress != 0){
|
|
|
|
|
percentageStr = Intl.NumberFormat("en-US", { style: "percent"}).format(json.progress);
|
|
|
|
|
timeleftStr = json.timeRemaining.split('.')[0];
|
|
|
|
|
}
|
|
|
|
|
progressSpan.innerText = `${percentageStr} ${timeleftStr}`;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function GetValidSelector(str){
|
|
|
|
|
var clean = [...str.matchAll(/[a-zA-Z0-9]*-*_*/g)];
|
|
|
|
|
return clean.join('');
|
2023-09-20 14:30:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const stringToColour = (str) => {
|
|
|
|
|
let hash = 0;
|
|
|
|
|
str.split('').forEach(char => {
|
|
|
|
|
hash = char.charCodeAt(0) + ((hash << 5) - hash)
|
|
|
|
|
})
|
|
|
|
|
let colour = '#'
|
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
|
|
|
const value = (hash >> (i * 8)) & 0xff
|
|
|
|
|
colour += value.toString(16).padStart(2, '0')
|
|
|
|
|
}
|
|
|
|
|
return colour
|
2023-09-08 19:59:12 +02:00
|
|
|
|
}
|