merge
This commit is contained in:
commit
6d55a13e49
90
.github/workflows/docker-image-cuttingedge.yml
vendored
90
.github/workflows/docker-image-cuttingedge.yml
vendored
@ -1,45 +1,45 @@
|
|||||||
name: Docker Image CI
|
name: Docker Image CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "cuttingedge" ]
|
branches: [ "cuttingedge" ]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# https://github.com/docker/setup-qemu-action#usage
|
# https://github.com/docker/setup-qemu-action#usage
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2.2.0
|
uses: docker/setup-qemu-action@v2.2.0
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/docker-setup-buildx
|
# https://github.com/marketplace/actions/docker-setup-buildx
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@v3.3.0
|
uses: docker/setup-buildx-action@v3.3.0
|
||||||
|
|
||||||
# https://github.com/docker/login-action#docker-hub
|
# https://github.com/docker/login-action#docker-hub
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
# https://github.com/docker/build-push-action#multi-platform-image
|
# https://github.com/docker/build-push-action#multi-platform-image
|
||||||
- name: Build and push Website
|
- name: Build and push Website
|
||||||
uses: docker/build-push-action@v4.1.1
|
uses: docker/build-push-action@v4.1.1
|
||||||
with:
|
with:
|
||||||
context: ./Website
|
context: ./Website
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
#platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
#platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
pull: true
|
pull: true
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
glax/tranga-website:cuttingedge
|
glax/tranga-website:cuttingedge
|
||||||
|
10
.github/workflows/docker-image-dev.yml
vendored
10
.github/workflows/docker-image-dev.yml
vendored
@ -37,9 +37,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
context: ./Website
|
context: ./Website
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
#platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
#platforms: linux/amd63,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
pull: true
|
pull: true
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
|
||||||
glax/tranga-website:dev
|
|
||||||
|
94
.github/workflows/docker-image-master.yml
vendored
94
.github/workflows/docker-image-master.yml
vendored
@ -1,47 +1,47 @@
|
|||||||
name: Docker Image CI
|
name: Docker Image CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "master" ]
|
branches: [ "master" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "master" ]
|
branches: [ "master" ]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# https://github.com/docker/setup-qemu-action#usage
|
# https://github.com/docker/setup-qemu-action#usage
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2.2.0
|
uses: docker/setup-qemu-action@v2.2.0
|
||||||
|
|
||||||
# https://github.com/marketplace/actions/docker-setup-buildx
|
# https://github.com/marketplace/actions/docker-setup-buildx
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@v3.3.0
|
uses: docker/setup-buildx-action@v3.1.0
|
||||||
|
|
||||||
# https://github.com/docker/login-action#docker-hub
|
# https://github.com/docker/login-action#docker-hub
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
# https://github.com/docker/build-push-action#multi-platform-image
|
# https://github.com/docker/build-push-action#multi-platform-image
|
||||||
- name: Build and push Website
|
- name: Build and push Website
|
||||||
uses: docker/build-push-action@v4.1.1
|
uses: docker/build-push-action@v4.1.1
|
||||||
with:
|
with:
|
||||||
context: ./Website
|
context: ./
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
#platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
#platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
pull: true
|
pull: true
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
glax/tranga-website:latest
|
glax/tranga-website:latest
|
||||||
|
10
Dockerfile
10
Dockerfile
@ -1,4 +1,6 @@
|
|||||||
FROM nginx:alpine3.17-slim
|
FROM nginx:alpine3.17-slim
|
||||||
COPY . /usr/share/nginx/html
|
COPY ./Website /usr/share/nginx/html
|
||||||
EXPOSE 80
|
COPY ./nginx /etc/nginx
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
EXPOSE 80
|
||||||
|
ENV API_URL=http://tranga-api:6531
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
@ -1,346 +1,381 @@
|
|||||||
let apiUri = `${window.location.protocol}//${window.location.host.split(':')[0]}:6531`
|
//let apiUri = `${window.location.protocol}//${window.location.host}/api`
|
||||||
|
|
||||||
if(getCookie("apiUri") != ""){
|
let apiUri = `http://192.168.1.79:6531`;
|
||||||
apiUri = getCookie("apiUri");
|
|
||||||
}
|
// if(getCookie("apiUri") != ""){
|
||||||
setCookie("apiUri", apiUri);
|
// apiUri = getCookie("apiUri");
|
||||||
|
// }
|
||||||
function setCookie(cname, cvalue) {
|
// setCookie("apiUri", apiUri);
|
||||||
const d = new Date();
|
|
||||||
d.setTime(d.getTime() + (365*24*60*60*1000));
|
function setCookie(cname, cvalue) {
|
||||||
let expires = "expires="+ d.toUTCString();
|
const d = new Date();
|
||||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;samesite=strict";
|
d.setTime(d.getTime() + (365*24*60*60*1000));
|
||||||
}
|
let expires = "expires="+ d.toUTCString();
|
||||||
|
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;samesite=strict";
|
||||||
function getCookie(cname) {
|
}
|
||||||
let name = cname + "=";
|
|
||||||
let decodedCookie = decodeURIComponent(document.cookie);
|
function getCookie(cname) {
|
||||||
let ca = decodedCookie.split(';');
|
let name = cname + "=";
|
||||||
for(let i = 0; i < ca.length; i++) {
|
let decodedCookie = decodeURIComponent(document.cookie);
|
||||||
let c = ca[i];
|
let ca = decodedCookie.split(';');
|
||||||
while (c.charAt(0) == ' ') {
|
for(let i = 0; i < ca.length; i++) {
|
||||||
c = c.substring(1);
|
let c = ca[i];
|
||||||
}
|
while (c.charAt(0) == ' ') {
|
||||||
if (c.indexOf(name) == 0) {
|
c = c.substring(1);
|
||||||
return c.substring(name.length, c.length);
|
}
|
||||||
}
|
if (c.indexOf(name) == 0) {
|
||||||
}
|
return c.substring(name.length, c.length);
|
||||||
return "";
|
}
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
async function GetData(uri){
|
}
|
||||||
let request = await fetch(uri, {
|
|
||||||
method: 'GET',
|
async function GetData(uri){
|
||||||
headers: {
|
let request = await fetch(uri, {
|
||||||
'Accept': 'application/json'
|
method: 'GET',
|
||||||
}
|
headers: {
|
||||||
});
|
'Accept': 'application/json'
|
||||||
let json = await request.json();
|
}
|
||||||
return json;
|
});
|
||||||
}
|
let json = await request.json();
|
||||||
|
return json;
|
||||||
async function PostData(uri){
|
}
|
||||||
let request = await fetch(uri, {
|
|
||||||
method: 'POST'
|
async function PostData(uri){
|
||||||
});
|
let request = await fetch(uri, {
|
||||||
//console.log(request);
|
method: 'POST'
|
||||||
}
|
});
|
||||||
|
//console.log(request);
|
||||||
function DeleteData(uri){
|
}
|
||||||
fetch(uri, {
|
|
||||||
method: 'DELETE'
|
function DeleteData(uri){
|
||||||
});
|
fetch(uri, {
|
||||||
}
|
method: 'DELETE'
|
||||||
|
});
|
||||||
async function Ping(){
|
}
|
||||||
let ret = await GetData(`${apiUri}/Ping`);
|
|
||||||
return ret;
|
async function Ping(){
|
||||||
}
|
let ret = await GetData(`${apiUri}/Ping`);
|
||||||
|
return ret;
|
||||||
async function GetAvailableControllers(){
|
}
|
||||||
var uri = apiUri + "/Connectors";
|
|
||||||
let json = await GetData(uri);
|
async function GetAvailableControllers(){
|
||||||
return json;
|
var uri = apiUri + "/Connectors";
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetPublicationFromConnector(connector, title){
|
}
|
||||||
var uri;
|
|
||||||
if(title.includes("http")){
|
async function GetPublicationFromConnector(connector, title){
|
||||||
uri = `${apiUri}/Manga/FromConnector?connector=${connector}&url=${title}`;
|
var uri;
|
||||||
}else{
|
if(title.includes("http")){
|
||||||
uri = `${apiUri}/Manga/FromConnector?connector=${connector}&title=${title}`;
|
uri = `${apiUri}/Manga/FromConnector?connector=${connector}&url=${title}`;
|
||||||
}
|
}else{
|
||||||
let json = await GetData(uri);
|
uri = `${apiUri}/Manga/FromConnector?connector=${connector}&title=${title}`;
|
||||||
return json;
|
}
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetChapters(connector, internalId, language){
|
}
|
||||||
var uri = `${apiUri}/Manga/Chapters?connector=${connector}&internalId=${internalId}&translatedLanguage=${language}`;
|
|
||||||
let json = await GetData(uri);
|
async function GetChapters(connector, internalId, language){
|
||||||
return json;
|
var uri = `${apiUri}/Manga/Chapters?connector=${connector}&internalId=${internalId}&translatedLanguage=${language}`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
function GetCoverUrl(internalId){
|
}
|
||||||
return `${apiUri}/Manga/Cover?internalId=${internalId}`;
|
|
||||||
}
|
function GetCoverUrl(internalId){
|
||||||
|
return `${apiUri}/Manga/Cover?internalId=${internalId}`;
|
||||||
async function GetAllJobs(){
|
}
|
||||||
var uri = `${apiUri}/Jobs`;
|
|
||||||
let json = await GetData(uri);
|
async function GetAllJobs(){
|
||||||
return json;
|
var uri = `${apiUri}/Jobs`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetRunningJobs(){
|
}
|
||||||
var uri = `${apiUri}/Jobs/Running`;
|
|
||||||
let json = await GetData(uri);
|
async function GetRunningJobs(){
|
||||||
return json;
|
var uri = `${apiUri}/Jobs/Running`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetWaitingJobs(){
|
}
|
||||||
var uri = `${apiUri}/Jobs/Waiting`;
|
|
||||||
let json = await GetData(uri);
|
async function GetWaitingJobs(){
|
||||||
return json;
|
var uri = `${apiUri}/Jobs/Waiting`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetMonitorJobs(){
|
}
|
||||||
var uri = `${apiUri}/Jobs/MonitorJobs`;
|
|
||||||
let json = await GetData(uri);
|
async function GetMonitorJobs(){
|
||||||
return json;
|
var uri = `${apiUri}/Jobs/MonitorJobs`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetProgress(jobId){
|
}
|
||||||
var uri = `${apiUri}/Jobs/Progress?jobId=${jobId}`;
|
|
||||||
let json = await GetData(uri);
|
async function GetProgress(jobId){
|
||||||
return json;
|
var uri = `${apiUri}/Jobs/Progress?jobId=${jobId}`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetSettings(){
|
}
|
||||||
var uri = `${apiUri}/Settings`;
|
|
||||||
let json = await GetData(uri);
|
async function GetSettings(){
|
||||||
return json;
|
var uri = `${apiUri}/Settings`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetAvailableNotificationConnectors(){
|
}
|
||||||
var uri = `${apiUri}/NotificationConnectors/Types`;
|
|
||||||
let json = await GetData(uri);
|
async function GetAvailableNotificationConnectors(){
|
||||||
return json;
|
var uri = `${apiUri}/NotificationConnectors/Types`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetNotificationConnectors(){
|
}
|
||||||
var uri = `${apiUri}/NotificationConnectors`;
|
|
||||||
let json = await GetData(uri);
|
async function GetNotificationConnectors(){
|
||||||
return json;
|
var uri = `${apiUri}/NotificationConnectors`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetAvailableLibraryConnectors(){
|
}
|
||||||
var uri = `${apiUri}/LibraryConnectors/Types`;
|
|
||||||
let json = await GetData(uri);
|
async function GetAvailableLibraryConnectors(){
|
||||||
return json;
|
var uri = `${apiUri}/LibraryConnectors/Types`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetLibraryConnectors(){
|
}
|
||||||
var uri = `${apiUri}/LibraryConnectors`;
|
|
||||||
let json = await GetData(uri);
|
async function GetLibraryConnectors(){
|
||||||
return json;
|
var uri = `${apiUri}/LibraryConnectors`;
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
async function GetRateLimits() {
|
}
|
||||||
var uri = `${apiUri}/Settings/customRequestLimit`
|
|
||||||
let json = await GetData(uri);
|
async function GetRateLimits() {
|
||||||
return json;
|
var uri = `${apiUri}/Settings/customRequestLimit`
|
||||||
}
|
let json = await GetData(uri);
|
||||||
|
return json;
|
||||||
function CreateMonitorJob(connector, internalId, language){
|
}
|
||||||
var uri = `${apiUri}/Jobs/MonitorManga?connector=${connector}&internalId=${internalId}&interval=03:00:00&translatedLanguage=${language}`;
|
|
||||||
PostData(uri);
|
async function GetMangaChapters(connector, id) {
|
||||||
}
|
var uri = `${apiUri}/Manga/Chapters?connector=${connector}&internalId=${id}`
|
||||||
|
let json = await GetData(uri);
|
||||||
function CreateDownloadNewChaptersJob(connector, internalId, language){
|
return json;
|
||||||
var uri = `${apiUri}/Jobs/DownloadNewChapters?connector=${connector}&internalId=${internalId}&translatedLanguage=${language}`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
function CreateMonitorJob(connector, internalId, language, interval, folder = null, chapterNo){
|
||||||
|
var uri = `${apiUri}/Jobs/MonitorManga?connector=${connector}&internalId=${internalId}&interval=${interval}&translatedLanguage=${language}&ignoreBelowChapterNum=${chapterNo}`;
|
||||||
function StartJob(jobId){
|
if (folder != '') {
|
||||||
var uri = `${apiUri}/Jobs/StartNow?jobId=${jobId}`;
|
uri = uri.concat(`&customFolderName=${folder}`);
|
||||||
PostData(uri);
|
}
|
||||||
}
|
console.log(uri);
|
||||||
|
PostData(uri);
|
||||||
function UpdateDownloadLocation(downloadLocation){
|
}
|
||||||
var uri = `${apiUri}/Settings/UpdateDownloadLocation?downloadLocation=${downloadLocation}`;
|
|
||||||
PostData(uri);
|
function CreateDownloadNewChaptersJob(connector, internalId, language){
|
||||||
}
|
var uri = `${apiUri}/Jobs/DownloadNewChapters?connector=${connector}&internalId=${internalId}&translatedLanguage=${language}`;
|
||||||
|
PostData(uri);
|
||||||
function RefreshLibraryMetadata() {
|
}
|
||||||
var uri = `${apiUri}/Jobs/UpdateMetadata`;
|
|
||||||
PostData(uri);
|
function StartJob(jobId){
|
||||||
}
|
var uri = `${apiUri}/Jobs/StartNow?jobId=${jobId}`;
|
||||||
|
PostData(uri);
|
||||||
async function DownloadLogs() {
|
}
|
||||||
var uri = `${apiUri}/LogFile`;
|
|
||||||
|
function UpdateDownloadLocation(downloadLocation){
|
||||||
//Below taken from https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
|
var uri = `${apiUri}/Settings/UpdateDownloadLocation?downloadLocation=${downloadLocation}`;
|
||||||
fetch(uri)
|
PostData(uri);
|
||||||
.then((response) => response.body)
|
}
|
||||||
.then((rb) => {
|
|
||||||
const reader = rb.getReader();
|
function RefreshLibraryMetadata() {
|
||||||
|
var uri = `${apiUri}/Jobs/UpdateMetadata`;
|
||||||
return new ReadableStream({
|
PostData(uri);
|
||||||
start(controller) {
|
}
|
||||||
// The following function handles each data chunk
|
|
||||||
function push() {
|
function RefreshMangaMetadata(id) {
|
||||||
// "done" is a Boolean and value a "Uint8Array"
|
var uri = `${apiUri}/Jobs/UpdateMetadata?internalId=${id}`;
|
||||||
reader.read().then(({ done, value }) => {
|
PostData(uri);
|
||||||
// If there is no more data to read
|
}
|
||||||
if (done) {
|
|
||||||
console.log("done", done);
|
async function DownloadLogs() {
|
||||||
controller.close();
|
var uri = `${apiUri}/LogFile`;
|
||||||
return;
|
|
||||||
}
|
//Below taken from https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
|
||||||
// Get the data and send it to the browser via the controller
|
fetch(uri)
|
||||||
controller.enqueue(value);
|
.then((response) => response.body)
|
||||||
// Check chunks by logging to the console
|
.then((rb) => {
|
||||||
console.log(done, value);
|
const reader = rb.getReader();
|
||||||
push();
|
|
||||||
});
|
return new ReadableStream({
|
||||||
}
|
start(controller) {
|
||||||
|
// The following function handles each data chunk
|
||||||
push();
|
function push() {
|
||||||
},
|
// "done" is a Boolean and value a "Uint8Array"
|
||||||
});
|
reader.read().then(({ done, value }) => {
|
||||||
})
|
// If there is no more data to read
|
||||||
.then((stream) =>
|
if (done) {
|
||||||
// Respond with our stream
|
console.log("done", done);
|
||||||
new Response(stream, { headers: { "Content-Type": "text/html" } }).text(),
|
controller.close();
|
||||||
)
|
return;
|
||||||
.then((result) => {
|
}
|
||||||
// Do things with result
|
// Get the data and send it to the browser via the controller
|
||||||
//console.log(result);
|
controller.enqueue(value);
|
||||||
|
// Check chunks by logging to the console
|
||||||
//Below download taken from https://stackoverflow.com/questions/3665115/how-to-create-a-file-in-memory-for-user-to-download-but-not-through-server
|
console.log(done, value);
|
||||||
var element = document.createElement('a');
|
push();
|
||||||
element.setAttribute('href', 'data:text/plain;charset-utf-8,' + encodeURIComponent(result));
|
});
|
||||||
var newDate = new Date();
|
}
|
||||||
var filename = "Tranga_Logs_" + newDate.today() + "_" + newDate.timeNow() + ".log";
|
|
||||||
element.setAttribute('download', filename);
|
push();
|
||||||
element.click();
|
},
|
||||||
});
|
});
|
||||||
}
|
})
|
||||||
|
.then((stream) =>
|
||||||
//Following date-time code taken from: https://stackoverflow.com/questions/10211145/getting-current-date-and-time-in-javascript
|
// Respond with our stream
|
||||||
// For todays date;
|
new Response(stream, { headers: { "Content-Type": "text/html" } }).text(),
|
||||||
Date.prototype.today = function () {
|
)
|
||||||
return ((this.getDate() < 10)?"0":"") + this.getDate() +"/"+(((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ this.getFullYear();
|
.then((result) => {
|
||||||
}
|
// Do things with result
|
||||||
|
//console.log(result);
|
||||||
// For the time now
|
|
||||||
Date.prototype.timeNow = function () {
|
//Below download taken from https://stackoverflow.com/questions/3665115/how-to-create-a-file-in-memory-for-user-to-download-but-not-through-server
|
||||||
return ((this.getHours() < 10)?"0":"") + this.getHours() +"_"+ ((this.getMinutes() < 10)?"0":"") + this.getMinutes() +"_"+ ((this.getSeconds() < 10)?"0":"") + this.getSeconds();
|
var element = document.createElement('a');
|
||||||
}
|
element.setAttribute('href', 'data:text/plain;charset-utf-8,' + encodeURIComponent(result));
|
||||||
|
var newDate = new Date();
|
||||||
//Komga
|
var filename = "Tranga_Logs_" + newDate.today() + "_" + newDate.timeNow() + ".log";
|
||||||
function UpdateKomga(komgaUrl, komgaAuth){
|
element.setAttribute('download', filename);
|
||||||
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
|
element.click();
|
||||||
PostData(uri);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ResetKomga(){
|
//Following date-time code taken from: https://stackoverflow.com/questions/10211145/getting-current-date-and-time-in-javascript
|
||||||
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Komga`;
|
// For todays date;
|
||||||
PostData(uri);
|
Date.prototype.today = function () {
|
||||||
}
|
return ((this.getDate() < 10)?"0":"") + this.getDate() +"/"+(((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ this.getFullYear();
|
||||||
|
}
|
||||||
function TestKomga(komgaUrl, komgaAuth){
|
|
||||||
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
|
// For the time now
|
||||||
PostData(uri);
|
Date.prototype.timeNow = function () {
|
||||||
}
|
return ((this.getHours() < 10)?"0":"") + this.getHours() +"_"+ ((this.getMinutes() < 10)?"0":"") + this.getMinutes() +"_"+ ((this.getSeconds() < 10)?"0":"") + this.getSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
//Kavita
|
function UpdateAprilFoolsMode() {
|
||||||
function UpdateKavita(kavitaUrl, kavitaUsername, kavitaPassword){
|
checkBox = document.getElementById("aprilFoolsMode");
|
||||||
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
|
var uri = `${apiUri}/Settings/AprilFoolsMode?enabled=${checkBox.checked}`;
|
||||||
PostData(uri);
|
PostData(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ResetKavita(){
|
function ResetRateLimits() {
|
||||||
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Kavita`;
|
var uri = `${apiUri}/Settings/customRequestLimit/Reset`;
|
||||||
PostData(uri);
|
PostData(uri);
|
||||||
}
|
OpenSettings();
|
||||||
|
}
|
||||||
function TestKavita(kavitaUrl, kavitaUsername, kavitaPassword){
|
|
||||||
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
|
function ResetUserAgent() {
|
||||||
PostData(uri);
|
var uri = `${apiUri}/Settings/userAgent/Reset`;
|
||||||
}
|
PostData(uri);
|
||||||
|
OpenSettings();
|
||||||
//Gotify
|
}
|
||||||
function UpdateGotify(gotifyUrl, gotifyAppToken){
|
|
||||||
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
|
//Komga
|
||||||
PostData(uri);
|
function UpdateKomga(komgaUrl, komgaAuth){
|
||||||
}
|
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
|
||||||
|
PostData(uri);
|
||||||
function ResetGotify(){
|
}
|
||||||
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Gotify`;
|
|
||||||
PostData(uri);
|
function ResetKomga(){
|
||||||
}
|
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Komga`;
|
||||||
|
PostData(uri);
|
||||||
function TestGotify(gotifyUrl, gotifyAppToken){
|
}
|
||||||
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
|
|
||||||
PostData(uri);
|
function TestKomga(komgaUrl, komgaAuth){
|
||||||
}
|
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
|
||||||
|
PostData(uri);
|
||||||
//LunaSea
|
}
|
||||||
function UpdateLunaSea(lunaseaWebhook){
|
|
||||||
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
|
|
||||||
PostData(uri);
|
//Kavita
|
||||||
}
|
function UpdateKavita(kavitaUrl, kavitaUsername, kavitaPassword){
|
||||||
|
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
|
||||||
function ResetLunaSea(){
|
PostData(uri);
|
||||||
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=LunaSea`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
function ResetKavita(){
|
||||||
|
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Kavita`;
|
||||||
function TestLunaSea(lunaseaWebhook){
|
PostData(uri);
|
||||||
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
function TestKavita(kavitaUrl, kavitaUsername, kavitaPassword){
|
||||||
|
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
|
||||||
//Ntfy
|
PostData(uri);
|
||||||
function UpdateNtfy(ntfyEndpoint, ntfyAuth){
|
}
|
||||||
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyAuth=${ntfyAuth}`;
|
|
||||||
PostData(uri);
|
//Gotify
|
||||||
}
|
function UpdateGotify(gotifyUrl, gotifyAppToken){
|
||||||
|
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
|
||||||
function ResetNtfy(){
|
PostData(uri);
|
||||||
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Ntfy`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
function ResetGotify(){
|
||||||
|
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Gotify`;
|
||||||
function TestNtfy(ntfyEndpoint, ntfyAuth){
|
PostData(uri);
|
||||||
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyAuth=${ntfyAuth}`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
function TestGotify(gotifyUrl, gotifyAppToken){
|
||||||
|
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
|
||||||
function UpdateUserAgent(userAgent){
|
PostData(uri);
|
||||||
var uri = `${apiUri}/Settings/userAgent?userAgent=${userAgent}`;
|
}
|
||||||
PostData(uri);
|
|
||||||
}
|
//LunaSea
|
||||||
|
function UpdateLunaSea(lunaseaWebhook){
|
||||||
function UpdateRateLimit(byteValue, rateLimit) {
|
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
|
||||||
var uri = `${apiUri}/Settings/customRequestLimit?requestType=${byteValue}&requestsPerMinute=${rateLimit}`;
|
PostData(uri);
|
||||||
PostData(uri);
|
}
|
||||||
}
|
|
||||||
|
function ResetLunaSea(){
|
||||||
function RemoveJob(jobId){
|
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=LunaSea`;
|
||||||
var uri = `${apiUri}/Jobs?jobId=${jobId}`;
|
PostData(uri);
|
||||||
DeleteData(uri);
|
}
|
||||||
}
|
|
||||||
|
function TestLunaSea(lunaseaWebhook){
|
||||||
function CancelJob(jobId){
|
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
|
||||||
var uri = `${apiUri}/Jobs/Cancel?jobId=${jobId}`;
|
PostData(uri);
|
||||||
PostData(uri);
|
}
|
||||||
}
|
|
||||||
|
//Ntfy
|
||||||
async function GetLogmessages(count){
|
function UpdateNtfy(ntfyEndpoint, ntfyUser, ntfyPass){
|
||||||
var uri = `${apiUri}/LogMessages?count=${count}`;
|
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyUser=${ntfyUser}&ntfyPass=${ntfyPass}`;
|
||||||
let json = await GetData(uri);
|
PostData(uri);
|
||||||
console.log(json);
|
}
|
||||||
return json;
|
|
||||||
}
|
function ResetNtfy(){
|
||||||
|
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Ntfy`;
|
||||||
|
PostData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TestNtfy(ntfyEndpoint, ntfyUser, ntfyPass){
|
||||||
|
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyUser=${ntfyUser}&ntfyPass=${ntfyPass}}`;
|
||||||
|
PostData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateUserAgent(userAgent){
|
||||||
|
var uri = `${apiUri}/Settings/userAgent?userAgent=${userAgent}`;
|
||||||
|
PostData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateRateLimit(byteValue, rateLimit) {
|
||||||
|
var uri = `${apiUri}/Settings/customRequestLimit?requestType=${byteValue}&requestsPerMinute=${rateLimit}`;
|
||||||
|
PostData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RemoveJob(jobId){
|
||||||
|
var uri = `${apiUri}/Jobs?jobId=${jobId}`;
|
||||||
|
DeleteData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CancelJob(jobId){
|
||||||
|
var uri = `${apiUri}/Jobs/Cancel?jobId=${jobId}`;
|
||||||
|
PostData(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetLogmessages(count){
|
||||||
|
var uri = `${apiUri}/LogMessages?count=${count}`;
|
||||||
|
let json = await GetData(uri);
|
||||||
|
console.log(json);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
@ -6,6 +6,10 @@
|
|||||||
<link id='basestyle' rel="stylesheet" href="styles/base.css">
|
<link id='basestyle' rel="stylesheet" href="styles/base.css">
|
||||||
<link id='librarystyle' rel="stylesheet" href="styles/style_default.css">
|
<link id='librarystyle' rel="stylesheet" href="styles/style_default.css">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400..900&display=swap" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<wrapper>
|
<wrapper>
|
||||||
@ -23,7 +27,7 @@
|
|||||||
<filter-box id="filterBox">
|
<filter-box id="filterBox">
|
||||||
<border-bar>
|
<border-bar>
|
||||||
<popup-title>Filter by: </popup-title>
|
<popup-title>Filter by: </popup-title>
|
||||||
<popup-close onclick="filterBox.classList.toggle('animate')" >×</popup-close>
|
<popup-close onclick="filterBox.style.display = 'none';" >×</popup-close>
|
||||||
</border-bar>
|
</border-bar>
|
||||||
<popup-content id="filterContent">
|
<popup-content id="filterContent">
|
||||||
<div class="popup-section">
|
<div class="popup-section">
|
||||||
@ -68,16 +72,27 @@
|
|||||||
|
|
||||||
<popup id="newMangaPopup">
|
<popup id="newMangaPopup">
|
||||||
<blur-background id="blurBackgroundNewMangaPopup" onclick="newMangaPopup.style.display = 'none';"></blur-background>
|
<blur-background id="blurBackgroundNewMangaPopup" onclick="newMangaPopup.style.display = 'none';"></blur-background>
|
||||||
<div id="newMangaPopupSelector">
|
<popup-window>
|
||||||
<select id="newMangaConnector" />
|
<border-bar>
|
||||||
<input type="text" placeholder="Title" id="newMangaTitle" />
|
<popup-title>Search</popup-title>
|
||||||
<select id="newMangaTranslatedLanguage">
|
<popup-close onclick="newMangaPopup.style.display = 'none'">×</popup-close>
|
||||||
<option selected="selected">en</option>
|
</border-bar>
|
||||||
<option>it</option>
|
<popup-content>
|
||||||
<option>de</option>
|
<div id="loaderdiv">
|
||||||
</select>
|
<div id="loader"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="newMangaResult"></div>
|
<div id="newMangaPopupSelector">
|
||||||
|
<select id="newMangaConnector">
|
||||||
|
<input type="text" placeholder="Title" id="newMangaTitle" />
|
||||||
|
<select id="newMangaTranslatedLanguage">
|
||||||
|
<option selected="selected">EN</option>
|
||||||
|
<option>IT</option>
|
||||||
|
<option>DE</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="newMangaResult"></div>
|
||||||
|
</popup-content>
|
||||||
|
</popup-window>
|
||||||
</popup>
|
</popup>
|
||||||
|
|
||||||
<popup id="settingsPopup">
|
<popup id="settingsPopup">
|
||||||
@ -97,7 +112,14 @@
|
|||||||
<row><label for="settingApiUri">API URI:</label><input placeholder="https://" type="text" id="settingApiUri"></row>
|
<row><label for="settingApiUri">API URI:</label><input placeholder="https://" type="text" id="settingApiUri"></row>
|
||||||
<row><label for="userAgent">User Agent:</label><input placeholder="UserAgent" id="userAgent" type="text"></row>
|
<row><label for="userAgent">User Agent:</label><input placeholder="UserAgent" id="userAgent" type="text"></row>
|
||||||
<row>
|
<row>
|
||||||
<border-bar-button class="section" onclick="RefreshLibraryMetadata()">Refresh Library Metadata</border-bar-button>
|
<label for="aprilFoolsMode">Skip Chapters on April 1st:</label>
|
||||||
|
<label class="switch-toggle">
|
||||||
|
<input type="checkbox" onclick="UpdateAprilFoolsMode()" id="aprilFoolsMode">
|
||||||
|
<span class="slider"></span>
|
||||||
|
</label>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<border-bar-button class="section" onclick="ResetUserAgent()">Reset User Agent</border-bar-button>
|
||||||
<border-bar-button class="section" onclick="DownloadLogs()">Download Logs</border-bar-button>
|
<border-bar-button class="section" onclick="DownloadLogs()">Download Logs</border-bar-button>
|
||||||
</row>
|
</row>
|
||||||
</div>
|
</div>
|
||||||
@ -107,13 +129,19 @@
|
|||||||
<row><label for="CoverRL">Manga Covers:</label><input id="coverRL" type="text"></row>
|
<row><label for="CoverRL">Manga Covers:</label><input id="coverRL" type="text"></row>
|
||||||
<row><label for="ImageRL">Manga Images:</label><input id="imageRL" type="text"></row>
|
<row><label for="ImageRL">Manga Images:</label><input id="imageRL" type="text"></row>
|
||||||
<row><label for="InfoRL">Manga Info:</label><input id="infoRL" type="text"></row>
|
<row><label for="InfoRL">Manga Info:</label><input id="infoRL" type="text"></row>
|
||||||
|
<row>
|
||||||
|
<border-bar-button class="section" onclick="ResetRateLimits()">Reset All Rate Limits</border-bar-button>
|
||||||
|
</row>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-item dyn-height">
|
<div class="section-item dyn-height">
|
||||||
<span class="title">Appearance</span>
|
<span class="title">Library</span>
|
||||||
<row><label for="cssStyle">Library Style:</label><select id="cssStyle">
|
<row><label for="cssStyle">Appearance Style:</label><select id="cssStyle">
|
||||||
<option id="card_compact" value="card_compact">Cards (Compact)</option>
|
<option id="card_compact" value="card_compact">Cards (Compact)</option>
|
||||||
<option id="card_hover" value="card_hover">Cards (Hover)</option>
|
<option id="card_hover" value="card_hover">Cards (Hover)</option>
|
||||||
</select></row>
|
</select></row>
|
||||||
|
<row>
|
||||||
|
<border-bar-button class="section" onclick="RefreshLibraryMetadata()">Refresh Library Metadata</border-bar-button>
|
||||||
|
</row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -131,7 +159,6 @@
|
|||||||
</div> -->
|
</div> -->
|
||||||
<div class="section-item dyn-height">
|
<div class="section-item dyn-height">
|
||||||
<span class="title"><img src="connector-icons/mangadex-logo.svg"><a href="https://mangadex.org">MangaDex</a></span>
|
<span class="title"><img src="connector-icons/mangadex-logo.svg"><a href="https://mangadex.org">MangaDex</a></span>
|
||||||
<row><label for="mDexAuthorRL">Author Rate Limit:</label><input id="mDexAuthorRL" type="text"></row>
|
|
||||||
<row><label for="mDexFeedRL">Feed Rate Limit:</label><input id="mDexFeedRL" type="text"></row>
|
<row><label for="mDexFeedRL">Feed Rate Limit:</label><input id="mDexFeedRL" type="text"></row>
|
||||||
<row><label for="mDexImageRL">Image Rate Limit:</label><input id="mDexImageRL" type="text"></row>
|
<row><label for="mDexImageRL">Image Rate Limit:</label><input id="mDexImageRL" type="text"></row>
|
||||||
</div>
|
</div>
|
||||||
@ -208,11 +235,12 @@
|
|||||||
<div class="section-item">
|
<div class="section-item">
|
||||||
<span class="title"><img src='connector-icons/ntfy.svg'>Ntfy<connector-configured id="ntfyConfigured"></connector-configured></span>
|
<span class="title"><img src='connector-icons/ntfy.svg'>Ntfy<connector-configured id="ntfyConfigured"></connector-configured></span>
|
||||||
<label for="ntfyEndpoint"></label><input placeholder="URL" id="ntfyEndpoint" type="text">
|
<label for="ntfyEndpoint"></label><input placeholder="URL" id="ntfyEndpoint" type="text">
|
||||||
<label for="ntfyAuth"></label><input placeholder="Auth" id="ntfyAuth" type="text">
|
<label for="ntfyUser"></label><input placeholder="Username" id="ntfyUser" type="text">
|
||||||
|
<label for="ntfyPass"></label><input placeholder="Password" id="ntfyPass" type="password">
|
||||||
<div class="section-buttons-container">
|
<div class="section-buttons-container">
|
||||||
<span onclick="TestNtfy(ntfyEndpoint.value, ntfyAuth.value);" class='section-button' id="test-connector">Test</span>
|
<span onclick="TestNtfy(ntfyEndpoint.value, ntfyUser.value, ntfyPass.value);" class='section-button' id="test-connector">Test</span>
|
||||||
<span onclick="ClearNtfy()" class='section-button' id="reset">Reset</span>
|
<span onclick="ClearNtfy()" class='section-button' id="reset">Reset</span>
|
||||||
<span onclick="UpdateNtfy(ntfyEndpoint.value, ntfyAuth.value);" class='section-button'>Apply</span>
|
<span onclick="UpdateNtfy(ntfyEndpoint.value, ntfyUser.value, ntfyPass.value);" class='section-button'>Apply</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -230,24 +258,32 @@
|
|||||||
|
|
||||||
<popup id="publicationViewerPopup">
|
<popup id="publicationViewerPopup">
|
||||||
<blur-background id="blurBackgroundPublicationPopup" onclick="publicationViewerPopup.style.display= 'none';"></blur-background>
|
<blur-background id="blurBackgroundPublicationPopup" onclick="publicationViewerPopup.style.display= 'none';"></blur-background>
|
||||||
<publication-viewer>
|
<popup-window>
|
||||||
<img id="pubviewcover" src="media/cover.jpg" alt="cover">
|
<border-bar>
|
||||||
<publication-details>
|
<popup-title><a class="mangaTitle" id="publicationViewerName"></a></popup-title><status-filter id="publicationViewerStatus"></status-filter>
|
||||||
<publication-name id="publicationViewerName">Best Manga there is</publication-name>
|
<popup-close onclick="publicationViewerPopup.style.display = 'none'">×</popup-close>
|
||||||
<publication-tags id="publicationViewerTags">A Manga</publication-tags>
|
</border-bar>
|
||||||
<publication-author id="publicationViewerAuthor">Glax</publication-author>
|
<manga-details>
|
||||||
<publication-description id="publicationViewerDescription">
|
|
||||||
An interesting description. The description is very intriguing, yet wholesome.
|
<img-container>
|
||||||
</publication-description>
|
<img id="pubviewcover">
|
||||||
<publication-interactions>
|
<manga-connector id="publicationViewerConnector"></manga-connector>
|
||||||
<publication-starttask id="startJobButton">Start Job ▶️</publication-starttask>
|
<span class="latest-chapter-no" id="publicationViewerChapterNo"></span>
|
||||||
<publication-canceltask id="cancelJobButton">Cancel Job ❌</publication-canceltask>
|
</img-container>
|
||||||
<publication-delete id="deleteJobButton">Delete Job 🗑️</publication-delete>
|
<div style="height: 100%;">
|
||||||
<publication-add id="createMonitorJobButton">Monitor ➕</publication-add>
|
<tag-cloud id="publicationViewerTags"></tag-cloud>
|
||||||
<publication-add id="createDownloadChapterJobButton">Download Chapter 📥</publication-add>
|
<div class="mangaDescription" id="publicationViewerDescription"></div>
|
||||||
</publication-interactions>
|
</div>
|
||||||
</publication-details>
|
</manga-details>
|
||||||
</publication-viewer>
|
<!-- <manga-chapter id="publicationViewerChapters"></manga-chapter> -->
|
||||||
|
<border-bar>
|
||||||
|
<div class="button-container">
|
||||||
|
<border-bar-button onclick="RefreshMangaMetadata(selectedManga.internalId)">Refresh Metadata</border-bar-button>
|
||||||
|
<border-bar-button id="reset" onclick="RemoveJob(selectedJob.id); UpdateJobs(); mangaViewerPopup.style.display = 'none'">Remove Manga</border-bar-button>
|
||||||
|
<border-bar-button class="primary" onclick="StartJob(selectedJob.id); mangaViewerPopup.style.display = 'none'">Start Job</border-bar-button>
|
||||||
|
</div>
|
||||||
|
</border-bar>
|
||||||
|
</popup-window>
|
||||||
</popup>
|
</popup>
|
||||||
|
|
||||||
<popup id="jobStatusView">
|
<popup id="jobStatusView">
|
||||||
@ -282,6 +318,7 @@
|
|||||||
</border-bar>
|
</border-bar>
|
||||||
|
|
||||||
</popup-window>
|
</popup-window>
|
||||||
|
</popup>
|
||||||
</viewport>
|
</viewport>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
let monitoringJobsCount = 0;
|
let monitoringJobsCount = 0;
|
||||||
let runningJobs = [];
|
let runningJobs = [];
|
||||||
let waitingJobs = [];
|
let waitingJobs = [];
|
||||||
let notificationConnectorTypes = [];
|
let notificationConnectorTypes = [];
|
||||||
@ -15,14 +15,10 @@ let statusNameMatch = [];
|
|||||||
const searchBox = document.querySelector("#searchbox");
|
const searchBox = document.querySelector("#searchbox");
|
||||||
const settingsPopup = document.querySelector("#settingsPopup");
|
const settingsPopup = document.querySelector("#settingsPopup");
|
||||||
const filterBox = document.querySelector("#filterBox");
|
const filterBox = document.querySelector("#filterBox");
|
||||||
|
const filterContent = document.querySelector("#filterContent");
|
||||||
const settingsCog = document.querySelector("#settingscog");
|
const settingsCog = document.querySelector("#settingscog");
|
||||||
const filterFunnel = document.querySelector("#filterFunnel");
|
const filterFunnel = document.querySelector("#filterFunnel");
|
||||||
const tasksContent = document.querySelector("content");
|
const tasksContent = document.querySelector("content");
|
||||||
const createMonitorTaskButton = document.querySelector("#createMonitoJobButton");
|
|
||||||
const createDownloadChapterTaskButton = document.querySelector("#createDownloadChapterJobButton");
|
|
||||||
const startJobButton = document.querySelector("#startJobButton");
|
|
||||||
const cancelJobButton = document.querySelector("#cancelJobButton");
|
|
||||||
const deleteJobButton = document.querySelector("#deleteJobButton");
|
|
||||||
|
|
||||||
//Manga viewer popup
|
//Manga viewer popup
|
||||||
const mangaViewerPopup = document.querySelector("#publicationViewerPopup");
|
const mangaViewerPopup = document.querySelector("#publicationViewerPopup");
|
||||||
@ -30,8 +26,10 @@ const mangaViewerWindow = document.querySelector("publication-viewer");
|
|||||||
const mangaViewerDescription = document.querySelector("#publicationViewerDescription");
|
const mangaViewerDescription = document.querySelector("#publicationViewerDescription");
|
||||||
const mangaViewerName = document.querySelector("#publicationViewerName");
|
const mangaViewerName = document.querySelector("#publicationViewerName");
|
||||||
const mangaViewerTags = document.querySelector("#publicationViewerTags");
|
const mangaViewerTags = document.querySelector("#publicationViewerTags");
|
||||||
const mangaViewerAuthor = document.querySelector("#publicationViewerAuthor");
|
|
||||||
const mangaViewCover = document.querySelector("#pubviewcover");
|
const mangaViewCover = document.querySelector("#pubviewcover");
|
||||||
|
const mangaViewConn = document.querySelector('#publicationViewerConnector');
|
||||||
|
const mangaViewStatus = document.querySelector('#publicationViewerStatus');
|
||||||
|
const mangaViewChapterNo = document.querySelector('#publicationViewerChapterNo');
|
||||||
|
|
||||||
//General Rate Limits
|
//General Rate Limits
|
||||||
const defaultRL = document.querySelector("#defaultRL");
|
const defaultRL = document.querySelector("#defaultRL");
|
||||||
@ -40,7 +38,6 @@ const imageRL = document.querySelector("#imageRL");
|
|||||||
const infoRL = document.querySelector("#infoRL");
|
const infoRL = document.querySelector("#infoRL");
|
||||||
|
|
||||||
//MangaDex Rate Limits
|
//MangaDex Rate Limits
|
||||||
const mDexAuthorRL = document.querySelector("#mDexAuthorRL");
|
|
||||||
const mDexFeedRL = document.querySelector("#mDexFeedRL");
|
const mDexFeedRL = document.querySelector("#mDexFeedRL");
|
||||||
const mDexImageRL = document.querySelector("#mDexImageRL");
|
const mDexImageRL = document.querySelector("#mDexImageRL");
|
||||||
|
|
||||||
@ -63,7 +60,8 @@ const settingLunaseaWebhook = document.querySelector("#lunaseaWebhook");
|
|||||||
|
|
||||||
//Ntfy
|
//Ntfy
|
||||||
const settingNtfyEndpoint = document.querySelector("#ntfyEndpoint");
|
const settingNtfyEndpoint = document.querySelector("#ntfyEndpoint");
|
||||||
const settingNtfyAuth = document.querySelector("#ntfyAuth");
|
const settingNtfyUser = document.querySelector("#ntfyUser");
|
||||||
|
const settingNtfyPass = document.querySelector("#ntfyPass");
|
||||||
|
|
||||||
//Connector Configured
|
//Connector Configured
|
||||||
const settingKomgaConfigured = document.querySelector("#komgaConfigured");
|
const settingKomgaConfigured = document.querySelector("#komgaConfigured");
|
||||||
@ -74,12 +72,17 @@ const settingNtfyConfigured = document.querySelector("#ntfyConfigured");
|
|||||||
|
|
||||||
const settingUserAgent = document.querySelector("#userAgent");
|
const settingUserAgent = document.querySelector("#userAgent");
|
||||||
const settingApiUri = document.querySelector("#settingApiUri");
|
const settingApiUri = document.querySelector("#settingApiUri");
|
||||||
|
const settingAprilFoolsMode = document.querySelector("#aprilFoolsMode");
|
||||||
const settingCSSStyle = document.querySelector('#cssStyle');
|
const settingCSSStyle = document.querySelector('#cssStyle');
|
||||||
|
const settingDownloadLocation = [];
|
||||||
|
|
||||||
|
//Search and Add
|
||||||
const newMangaPopup = document.querySelector("#newMangaPopup");
|
const newMangaPopup = document.querySelector("#newMangaPopup");
|
||||||
const newMangaConnector = document.querySelector("#newMangaConnector");
|
const newMangaConnector = document.querySelector("#newMangaConnector");
|
||||||
const newMangaTitle = document.querySelector("#newMangaTitle");
|
const newMangaTitle = document.querySelector("#newMangaTitle");
|
||||||
const newMangaResult = document.querySelector("#newMangaResult");
|
const newMangaResult = document.querySelector("#newMangaResult");
|
||||||
const newMangaTranslatedLanguage = document.querySelector("#newMangaTranslatedLanguage");
|
const newMangaTranslatedLanguage = document.querySelector("#newMangaTranslatedLanguage");
|
||||||
|
const newMangaLoader = document.querySelector("popup-content #loaderdiv");
|
||||||
|
|
||||||
//Jobs
|
//Jobs
|
||||||
const jobsRunningTag = document.querySelector("#jobsRunningTag");
|
const jobsRunningTag = document.querySelector("#jobsRunningTag");
|
||||||
@ -152,13 +155,15 @@ function Setup(){
|
|||||||
GetSettings().then((json) => {
|
GetSettings().then((json) => {
|
||||||
//console.log(json);
|
//console.log(json);
|
||||||
settingApiUri.placeholder = apiUri;
|
settingApiUri.placeholder = apiUri;
|
||||||
|
settingDownloadLocation.placeholder = json.downloadLocation;
|
||||||
|
settingUserAgent.placeholder = json.userAgent;
|
||||||
|
settingAprilFoolsMode.checked = json.aprilFoolsMode;
|
||||||
});
|
});
|
||||||
GetRateLimits().then((json) => {
|
GetRateLimits().then((json) => {
|
||||||
defaultRL.placeholder = json.Default + ' Requests/Minute';
|
defaultRL.placeholder = json.Default + ' Requests/Minute';
|
||||||
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
|
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
|
||||||
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
|
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
|
||||||
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
|
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
|
||||||
mDexAuthorRL.placeholder = json.MangaDexAuthor + ' Requests/Minute';
|
|
||||||
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
|
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
|
||||||
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
|
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
|
||||||
});
|
});
|
||||||
@ -185,6 +190,15 @@ function Setup(){
|
|||||||
}
|
}
|
||||||
Setup();
|
Setup();
|
||||||
|
|
||||||
|
function ToggleFilterBox() {
|
||||||
|
if (filterBox.style.display == 'none') {
|
||||||
|
filterBox.style.display = 'flex';
|
||||||
|
} else {
|
||||||
|
filterBox.style.display = 'none';
|
||||||
|
}
|
||||||
|
filterContent.scrollTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function ToggleFilterConnector(connector, event) {
|
function ToggleFilterConnector(connector, event) {
|
||||||
//console.log("Initial Array:");
|
//console.log("Initial Array:");
|
||||||
//console.log(connectorMatch);
|
//console.log(connectorMatch);
|
||||||
@ -281,31 +295,30 @@ function ShowNewMangaSearch(){
|
|||||||
newMangaTitle.value = "";
|
newMangaTitle.value = "";
|
||||||
newMangaPopup.style.display = "block";
|
newMangaPopup.style.display = "block";
|
||||||
newMangaResult.replaceChildren();
|
newMangaResult.replaceChildren();
|
||||||
|
newMangaLoader.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
newMangaTitle.addEventListener("keypress", (event) => { if(event.key === "Enter") GetNewMangaItems();});
|
newMangaTitle.addEventListener("keypress", (event) => { if(event.key === "Enter") GetNewMangaItems();});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function GetNewMangaItems(){
|
function GetNewMangaItems(){
|
||||||
if(newMangaTitle.value.length < 4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if(newMangaTitle.value.length < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
newMangaResult.replaceChildren();
|
newMangaResult.replaceChildren();
|
||||||
newMangaConnector.disabled = true;
|
newMangaConnector.disabled = true;
|
||||||
newMangaTitle.disabled = true;
|
newMangaTitle.disabled = true;
|
||||||
newMangaTranslatedLanguage.disabled = true;
|
newMangaTranslatedLanguage.disabled = true;
|
||||||
|
newMangaLoader.style.display = 'block';
|
||||||
GetPublicationFromConnector(newMangaConnector.value, newMangaTitle.value).then((json) => {
|
GetPublicationFromConnector(newMangaConnector.value, newMangaTitle.value).then((json) => {
|
||||||
//console.log(json);
|
//console.log(json);
|
||||||
|
newMangaLoader.style.display = 'none';
|
||||||
|
newMangaResult.scrollTop = 0;
|
||||||
if(json.length > 0)
|
if(json.length > 0)
|
||||||
newMangaResult.style.display = "flex";
|
newMangaResult.style.display = "flex";
|
||||||
json.forEach(result => {
|
json.forEach(result => {
|
||||||
var mangaElement = CreateManga(result, newMangaConnector.value)
|
var searchResult = CreateSearchResult(result, newMangaConnector.value)
|
||||||
newMangaResult.appendChild(mangaElement);
|
newMangaResult.appendChild(searchResult);
|
||||||
mangaElement.addEventListener("click", (event) => {
|
|
||||||
ShowMangaWindow(null, result, event, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
newMangaConnector.disabled = false;
|
newMangaConnector.disabled = false;
|
||||||
@ -367,65 +380,289 @@ function CreateManga(manga, connector){
|
|||||||
return mangaElement;
|
return mangaElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
createMonitorJobButton.addEventListener("click", () => {
|
//Returns a new "Search Result" item to display in the search window
|
||||||
CreateMonitorJob(newMangaConnector.value, selectedManga.internalId, newMangaTranslatedLanguage.value);
|
function CreateSearchResult(manga, connector) {
|
||||||
UpdateJobs();
|
//Create a new publication and set an internal ID
|
||||||
mangaViewerPopup.style.display = "none";
|
var searchResult = document.createElement('div');
|
||||||
});
|
searchResult.id = GetValidSelector(manga.internalId);
|
||||||
startJobButton.addEventListener("click", () => {
|
searchResult.className = "section-item";
|
||||||
StartJob(selectedJob.id);
|
|
||||||
mangaViewerPopup.style.display = "none";
|
//Append the cover image to the publication
|
||||||
});
|
var imageCont = document.createElement('img-container');
|
||||||
cancelJobButton.addEventListener("click", () => {
|
|
||||||
CancelJob(selectedJob.id);
|
var mangaImage = document.createElement('img');
|
||||||
mangaViewerPopup.style.display = "none";
|
mangaImage.src = GetCoverUrl(manga.internalId);
|
||||||
});
|
imageCont.appendChild(mangaImage);
|
||||||
deleteJobButton.addEventListener("click", () => {
|
|
||||||
RemoveJob(selectedJob.id);
|
var connectorName = document.createElement('manga-connector');
|
||||||
UpdateJobs();
|
connectorName.innerText = connector.toUpperCase();
|
||||||
mangaViewerPopup.style.display = "none";
|
connectorName.style.backgroundColor = stringToColour(connector);
|
||||||
});
|
imageCont.appendChild(connectorName);
|
||||||
|
|
||||||
|
var chapterNo = document.createElement('span');
|
||||||
|
chapterNo.className = 'latest-chapter-no';
|
||||||
|
chapterNo.innerText = manga.latestChapterAvailable.toString();
|
||||||
|
imageCont.appendChild(chapterNo);
|
||||||
|
|
||||||
|
searchResult.appendChild(imageCont);
|
||||||
|
|
||||||
|
var mangaDetails = document.createElement('div');
|
||||||
|
mangaDetails.className = 'jobDetails';
|
||||||
|
|
||||||
|
var headerRow = document.createElement('header-row');
|
||||||
|
|
||||||
|
var mangaTitle = document.createElement('a');
|
||||||
|
mangaTitle.innerText = manga.sortName;
|
||||||
|
mangaTitle.href = manga.websiteUrl;
|
||||||
|
mangaTitle.className = 'mangaTitle';
|
||||||
|
headerRow.appendChild(mangaTitle);
|
||||||
|
|
||||||
|
//Create the publication status indicator
|
||||||
|
var releaseStatus = document.createElement('status-filter');
|
||||||
|
switch(manga.releaseStatus){
|
||||||
|
case 0:
|
||||||
|
releaseStatus.setAttribute("release-status", "Ongoing");
|
||||||
|
releaseStatus.innerText = "Ongoing";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
releaseStatus.setAttribute("release-status", "Completed");
|
||||||
|
releaseStatus.innerText = "Completed";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
releaseStatus.setAttribute("release-status", "On Hiatus");
|
||||||
|
releaseStatus.innerText = "On Hiatus";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
releaseStatus.setAttribute("release-status", "Cancelled");
|
||||||
|
releaseStatus.innerText = "Cancelled";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
releaseStatus.setAttribute("release-status", "Upcoming");
|
||||||
|
releaseStatus.innerText = "Upcoming";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
releaseStatus.setAttribute("release-status", "Status Unavailable");
|
||||||
|
releaseStatus.innerText = "Status Unavailable";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
headerRow.appendChild(releaseStatus);
|
||||||
|
|
||||||
|
mangaDetails.appendChild(headerRow);
|
||||||
|
|
||||||
|
//Genres
|
||||||
|
var tagCloud = document.createElement('tag-cloud');
|
||||||
|
manga.authors.forEach(author => {
|
||||||
|
var authorCard = document.createElement('author-tag');
|
||||||
|
|
||||||
|
var personImg = document.createElement('img');
|
||||||
|
personImg.src = 'media/person.svg';
|
||||||
|
authorCard.appendChild(personImg);
|
||||||
|
|
||||||
|
var authorName = document.createElement('span');
|
||||||
|
authorName.innerText = author;
|
||||||
|
authorCard.appendChild(authorName);
|
||||||
|
|
||||||
|
tagCloud.appendChild(authorCard);
|
||||||
|
});
|
||||||
|
manga.tags.forEach(tag => {
|
||||||
|
var tagElement = document.createElement('manga-tag');
|
||||||
|
tagElement.innerText = tag;
|
||||||
|
tagCloud.appendChild(tagElement);
|
||||||
|
});
|
||||||
|
mangaDetails.appendChild(tagCloud);
|
||||||
|
|
||||||
|
//Description
|
||||||
|
var description = document.createElement('div');
|
||||||
|
description.className = 'mangaDescription abbreviated';
|
||||||
|
description.innerText = manga.description;
|
||||||
|
mangaDetails.appendChild(description);
|
||||||
|
|
||||||
|
searchResult.appendChild(mangaDetails);
|
||||||
|
|
||||||
|
//Download Settings
|
||||||
|
var dlSett = document.createElement('div');
|
||||||
|
dlSett.className = 'new-manga-download-settings'
|
||||||
|
|
||||||
|
folderRow = document.createElement('row');
|
||||||
|
folderLabel = document.createElement('label');
|
||||||
|
folderLabel.innerText = 'Download Folder';
|
||||||
|
folderRow.appendChild(folderLabel);
|
||||||
|
folderInput = document.createElement('input');
|
||||||
|
downloadFolder = manga.folderName;
|
||||||
|
folderInput.placeholder = downloadFolder.toString();
|
||||||
|
folderInput.type = 'text';
|
||||||
|
folderInput.id = manga.internalId.concat('-downloadfolder')
|
||||||
|
folderRow.appendChild(folderInput);
|
||||||
|
dlSett.appendChild(folderRow);
|
||||||
|
|
||||||
|
intervalRow = document.createElement('row');
|
||||||
|
intervalLabel = document.createElement('label');
|
||||||
|
intervalLabel.innerText = 'Job Interval';
|
||||||
|
intervalRow.appendChild(intervalLabel);
|
||||||
|
intervalInput = document.createElement('input');
|
||||||
|
intervalInput.placeholder = '03:00:00 (HH:MM:SS)';
|
||||||
|
intervalInput.type = 'text';
|
||||||
|
intervalInput.id = manga.internalId.concat('-downloadinterval')
|
||||||
|
intervalRow.appendChild(intervalInput);
|
||||||
|
dlSett.appendChild(intervalRow);
|
||||||
|
|
||||||
|
chapterRow = document.createElement('row');
|
||||||
|
chapterLabel = document.createElement('label');
|
||||||
|
chapterLabel.innerText = 'Download from Chapter';
|
||||||
|
chapterRow.appendChild(chapterLabel);
|
||||||
|
chapterInput = document.createElement('input');
|
||||||
|
chapterInput.placeholder = (manga.ignoreChaptersBelow + 1).toString();
|
||||||
|
chapterInput.type = 'number';
|
||||||
|
chapterInput.id = manga.internalId.concat('-downloadchapter')
|
||||||
|
chapterRow.appendChild(chapterInput);
|
||||||
|
dlSett.appendChild(chapterRow);
|
||||||
|
|
||||||
|
dlButton = document.createElement('border-bar-button');
|
||||||
|
if (IsInLibrary(manga.internalId)) {
|
||||||
|
dlButton.className = 'section in-library';
|
||||||
|
dlButton.innerText = 'In Library';
|
||||||
|
} else {
|
||||||
|
dlButton.className = 'section downloadManga';
|
||||||
|
dlButton.innerText = 'Monitor Manga';
|
||||||
|
dlButton.addEventListener('click', function() { AddManga(manga.internalId, connector) });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dlSett.appendChild(dlButton);
|
||||||
|
|
||||||
|
mangaDetails.appendChild(dlSett);
|
||||||
|
|
||||||
|
//Append the publication information to the publication
|
||||||
|
//console.log(manga);
|
||||||
|
return searchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsInLibrary(id) {
|
||||||
|
matchFound = false;
|
||||||
|
tasksContent.childNodes.forEach(publication => {
|
||||||
|
if (id.toLowerCase().includes(publication.id.toLowerCase())) {
|
||||||
|
console.log('Match found');
|
||||||
|
matchFound = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return matchFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AddManga(id, connector) {
|
||||||
|
console.log('Adding Manga');
|
||||||
|
mangaID = id;
|
||||||
|
mangaConnector = connector;
|
||||||
|
mangaLanguage = document.getElementById('newMangaTranslatedLanguage').value.toLowerCase();
|
||||||
|
|
||||||
|
folderInput = document.getElementById(id.concat('-downloadfolder')).value;
|
||||||
|
if (folderInput != null || folderInput != '') {
|
||||||
|
mangaFolder = folderInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalInput = document.getElementById(id.concat('-downloadinterval')).value;
|
||||||
|
if (intervalInput == null || intervalInput == '') {
|
||||||
|
mangaInterval = '03:00:00';
|
||||||
|
} else {
|
||||||
|
mangaInterval = intervalInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
chapterInput = document.getElementById(id.concat('-downloadchapter')).value;
|
||||||
|
if (chapterInput == null || chapterInput == '') {
|
||||||
|
mangaChapter = 0;
|
||||||
|
} else {
|
||||||
|
mangaChapter = chapterInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateMonitorJob(mangaConnector, mangaID, mangaLanguage, mangaInterval, mangaFolder, mangaChapter);
|
||||||
|
}
|
||||||
|
|
||||||
function ShowMangaWindow(job, manga, event, add){
|
function ShowMangaWindow(job, manga, event, add){
|
||||||
selectedManga = manga;
|
selectedManga = manga;
|
||||||
selectedJob = job;
|
selectedJob = job;
|
||||||
//Show popup
|
|
||||||
mangaViewerPopup.style.display = "block";
|
|
||||||
|
|
||||||
//Set position to mouse-position
|
//Title
|
||||||
if(event.clientY < window.innerHeight - mangaViewerWindow.offsetHeight)
|
|
||||||
mangaViewerWindow.style.top = `${event.clientY}px`;
|
|
||||||
else
|
|
||||||
mangaViewerWindow.style.top = `${event.clientY - mangaViewerWindow.offsetHeight}px`;
|
|
||||||
|
|
||||||
if(event.clientX < window.innerWidth - mangaViewerWindow.offsetWidth)
|
|
||||||
mangaViewerWindow.style.left = `${event.clientX}px`;
|
|
||||||
else
|
|
||||||
mangaViewerWindow.style.left = `${event.clientX - mangaViewerWindow.offsetWidth}px`;
|
|
||||||
|
|
||||||
//Edit information inside the window
|
|
||||||
mangaViewerName.innerText = manga.sortName;
|
mangaViewerName.innerText = manga.sortName;
|
||||||
mangaViewerTags.innerText = manga.tags.join(", ");
|
mangaViewerName.href = manga.websiteUrl;
|
||||||
|
|
||||||
|
//Author and Genre Tag Cloud
|
||||||
|
mangaViewerTags.replaceChildren();
|
||||||
|
manga.authors.forEach(author => {
|
||||||
|
var authorCard = document.createElement('author-tag');
|
||||||
|
|
||||||
|
var personImg = document.createElement('img');
|
||||||
|
personImg.src = 'media/person.svg';
|
||||||
|
authorCard.appendChild(personImg);
|
||||||
|
|
||||||
|
var authorName = document.createElement('span');
|
||||||
|
authorName.innerText = author;
|
||||||
|
authorCard.appendChild(authorName);
|
||||||
|
|
||||||
|
mangaViewerTags.appendChild(authorCard);
|
||||||
|
});
|
||||||
|
manga.tags.forEach(tag => {
|
||||||
|
var tagElement = document.createElement('manga-tag');
|
||||||
|
tagElement.innerText = tag;
|
||||||
|
mangaViewerTags.appendChild(tagElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Description
|
||||||
mangaViewerDescription.innerText = manga.description;
|
mangaViewerDescription.innerText = manga.description;
|
||||||
mangaViewerAuthor.innerText = manga.authors.join(',');
|
|
||||||
|
//Image and Connector
|
||||||
mangaViewCover.src = GetCoverUrl(manga.internalId);
|
mangaViewCover.src = GetCoverUrl(manga.internalId);
|
||||||
toEditId = manga.internalId;
|
mangaViewConn.innerText = job.mangaConnector.name.toUpperCase();
|
||||||
|
mangaViewConn.style.backgroundColor = stringToColour(job.mangaConnector.name);
|
||||||
//Check what action should be listed
|
mangaViewChapterNo.innerText = manga.latestChapterAvailable.toString();
|
||||||
if(add){
|
|
||||||
createMonitorJobButton.style.display = "initial";
|
//Release Status
|
||||||
createDownloadChapterJobButton.style.display = "none";
|
switch(manga.releaseStatus){
|
||||||
cancelJobButton.style.display = "none";
|
case 0:
|
||||||
startJobButton.style.display = "none";
|
mangaViewStatus.setAttribute("release-status", "Ongoing");
|
||||||
deleteJobButton.style.display = "none";
|
mangaViewStatus.innerText = "Ongoing";
|
||||||
}
|
break;
|
||||||
else{
|
case 1:
|
||||||
createMonitorJobButton.style.display = "none";
|
mangaViewStatus.setAttribute("release-status", "Completed");
|
||||||
createDownloadChapterJobButton.style.display = "none";
|
mangaViewStatus.innerText = "Completed";
|
||||||
cancelJobButton.style.display = "initial";
|
break;
|
||||||
startJobButton.style.display = "initial";
|
case 2:
|
||||||
deleteJobButton.style.display = "initial";
|
mangaViewStatus.setAttribute("release-status", "On Hiatus");
|
||||||
|
mangaViewStatus.innerText = "On Hiatus";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mangaViewStatus.setAttribute("release-status", "Cancelled");
|
||||||
|
mangaViewStatus.innerText = "Cancelled";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
mangaViewStatus.setAttribute("release-status", "Upcoming");
|
||||||
|
mangaViewStatus.innerText = "Upcoming";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mangaViewStatus.setAttribute("release-status", "Status Unavailable");
|
||||||
|
mangaViewStatus.innerText = "Status Unavailable";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// //Individual Manga Chapters
|
||||||
|
// chapters = document.querySelector('#publicationViewerChapters');
|
||||||
|
// chapters.replaceChildren();
|
||||||
|
// var mangaChapters = GetMangaChapters(job.mangaConnector.name, manga.internalId);
|
||||||
|
|
||||||
|
// mangaChapters.then(value => {
|
||||||
|
|
||||||
|
// sortedChapters = value.sort((a, b) => b.chapterNumber - a.chapterNumber);
|
||||||
|
|
||||||
|
// sortedChapters.forEach(chapter => {
|
||||||
|
// chapterNo = chapter.chapterNumber;
|
||||||
|
// var chapterElement = document.createElement('chapter-row');
|
||||||
|
// chapterElement.innerText = chapter.fileName;
|
||||||
|
// chapters.appendChild(chapterElement);
|
||||||
|
// })
|
||||||
|
// }).then(() => {
|
||||||
|
// //Show popup
|
||||||
|
// mangaViewerPopup.style.display = "block";
|
||||||
|
// });
|
||||||
|
|
||||||
|
mangaViewerPopup.style.display = "block"
|
||||||
}
|
}
|
||||||
|
|
||||||
function HidePublicationPopup(){
|
function HidePublicationPopup(){
|
||||||
@ -509,7 +746,7 @@ settingsCog.addEventListener("click", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
filterFunnel.addEventListener("click", () => {
|
filterFunnel.addEventListener("click", () => {
|
||||||
filterBox.classList.toggle("animate");
|
ToggleFilterBox();
|
||||||
});
|
});
|
||||||
|
|
||||||
settingKomgaUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
settingKomgaUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
@ -522,7 +759,7 @@ settingGotifyUrl.addEventListener("keypress", (event) => { if(event.key === "Ent
|
|||||||
settingGotifyAppToken.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(); });
|
settingLunaseaWebhook.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
settingNtfyEndpoint.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
settingNtfyEndpoint.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
settingNtfyAuth.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
settingNtfyPass.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
settingUserAgent.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
settingUserAgent.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
settingApiUri.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
settingApiUri.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
|
||||||
|
|
||||||
@ -530,7 +767,6 @@ defaultRL.addEventListener("keypress", (event) => { if(event.key === "Enter") Up
|
|||||||
coverRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
coverRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
||||||
imageRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
imageRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
||||||
infoRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
infoRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
||||||
mDexAuthorRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
|
||||||
mDexFeedRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
mDexFeedRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
||||||
mDexImageRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
mDexImageRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
|
||||||
|
|
||||||
@ -550,7 +786,8 @@ function OpenSettings(){
|
|||||||
settingGotifyUrl.value = "";
|
settingGotifyUrl.value = "";
|
||||||
settingGotifyAppToken.value = "";
|
settingGotifyAppToken.value = "";
|
||||||
settingLunaseaWebhook.value = "";
|
settingLunaseaWebhook.value = "";
|
||||||
settingNtfyAuth.value = "";
|
settingNtfyUser.value = "";
|
||||||
|
settingNtfyPass.value = "";
|
||||||
settingNtfyEndpoint.value = "";
|
settingNtfyEndpoint.value = "";
|
||||||
settingUserAgent.value = "";
|
settingUserAgent.value = "";
|
||||||
settingApiUri.value = "";
|
settingApiUri.value = "";
|
||||||
@ -558,14 +795,15 @@ function OpenSettings(){
|
|||||||
coverRL.value = "";
|
coverRL.value = "";
|
||||||
imageRL.value = "";
|
imageRL.value = "";
|
||||||
infoRL.value = "";
|
infoRL.value = "";
|
||||||
mDexAuthorRL.value = "";
|
|
||||||
mDexFeedRL.value = "";
|
mDexFeedRL.value = "";
|
||||||
mDexImageRL.value = "";
|
mDexImageRL.value = "";
|
||||||
|
|
||||||
GetSettings().then((json) => {
|
GetSettings().then((json) => {
|
||||||
//console.log(json);
|
//console.log(json);
|
||||||
settingApiUri.value = apiUri;
|
settingApiUri.placeholder = apiUri;
|
||||||
settingUserAgent.value = json.userAgent;
|
settingUserAgent.placeholder = json.userAgent;
|
||||||
|
settingAprilFoolsMode.checked = json.aprilFoolsMode;
|
||||||
|
settingDownloadLocation.placeholder = json.downloadLocation;
|
||||||
//console.log(json.styleSheet);
|
//console.log(json.styleSheet);
|
||||||
});
|
});
|
||||||
GetRateLimits().then((json) => {
|
GetRateLimits().then((json) => {
|
||||||
@ -573,7 +811,6 @@ function OpenSettings(){
|
|||||||
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
|
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
|
||||||
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
|
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
|
||||||
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
|
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
|
||||||
mDexAuthorRL.placeholder = json.MangaDexAuthor + ' Requests/Minute';
|
|
||||||
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
|
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
|
||||||
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
|
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
|
||||||
});
|
});
|
||||||
@ -583,15 +820,15 @@ function OpenSettings(){
|
|||||||
switch(libraryConnectorTypes[connector.libraryType]){
|
switch(libraryConnectorTypes[connector.libraryType]){
|
||||||
case "Kavita":
|
case "Kavita":
|
||||||
settingKavitaConfigured.setAttribute("configuration", "Active");
|
settingKavitaConfigured.setAttribute("configuration", "Active");
|
||||||
settingKavitaUrl.value = connector.baseUrl;
|
settingKavitaUrl.placeholder = connector.baseUrl;
|
||||||
settingKavitaUser.value = "***";
|
settingKavitaUser.placeholder = "***";
|
||||||
settingKavitaPass.value = "***";
|
settingKavitaPass.placeholder = "***";
|
||||||
break;
|
break;
|
||||||
case "Komga":
|
case "Komga":
|
||||||
settingKomgaConfigured.setAttribute("configuration", "Active");
|
settingKomgaConfigured.setAttribute("configuration", "Active");
|
||||||
settingKomgaUrl.value = connector.baseUrl;
|
settingKomgaUrl.placeholder = connector.baseUrl;
|
||||||
settingKomgaUser.value = "***";
|
settingKomgaUser.placeholder = "***";
|
||||||
settingKomgaPass.value = "***";
|
settingKomgaPass.placeholder = "***";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Unknown type");
|
console.log("Unknown type");
|
||||||
@ -604,18 +841,19 @@ function OpenSettings(){
|
|||||||
json.forEach(connector => {
|
json.forEach(connector => {
|
||||||
switch(notificationConnectorTypes[connector.notificationConnectorType]){
|
switch(notificationConnectorTypes[connector.notificationConnectorType]){
|
||||||
case "Gotify":
|
case "Gotify":
|
||||||
settingGotifyUrl.value = connector.endpoint;
|
settingGotifyUrl.placeholder = connector.endpoint;
|
||||||
settingGotifyAppToken.value = "***";
|
settingGotifyAppToken.placeholder = "***";
|
||||||
settingGotifyConfigured.setAttribute("configuration", "Active");
|
settingGotifyConfigured.setAttribute("configuration", "Active");
|
||||||
break;
|
break;
|
||||||
case "LunaSea":
|
case "LunaSea":
|
||||||
settingLunaseaConfigured.setAttribute("configuration", "Active");
|
settingLunaseaConfigured.setAttribute("configuration", "Active");
|
||||||
settingLunaseaWebhook.value = connector.id;
|
settingLunaseaWebhook.placeholder = connector.id;
|
||||||
break;
|
break;
|
||||||
case "Ntfy":
|
case "Ntfy":
|
||||||
settingNtfyConfigured.setAttribute("configuration", "Active");
|
settingNtfyConfigured.setAttribute("configuration", "Active");
|
||||||
settingNtfyEndpoint.value = connector.endpoint;
|
settingNtfyEndpoint.placeholder = connector.endpoint;
|
||||||
settingNtfyAuth.value = "***";
|
settingNtfyUser.placeholder = "***"
|
||||||
|
settingNtfyPass.placeholder = "***";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Unknown type");
|
console.log("Unknown type");
|
||||||
@ -658,7 +896,8 @@ function ClearLunasea(){
|
|||||||
|
|
||||||
function ClearNtfy(){
|
function ClearNtfy(){
|
||||||
settingNtfyEndpoint.value = "";
|
settingNtfyEndpoint.value = "";
|
||||||
settingNtfyAuth.value = "";
|
settingNtfyUser.value = "";
|
||||||
|
settingNtfyPass.value = "";
|
||||||
settingNtfyConfigured.setAttribute("configuration", "Not Configured");
|
settingNtfyConfigured.setAttribute("configuration", "Not Configured");
|
||||||
ResetNtfy();
|
ResetNtfy();
|
||||||
}
|
}
|
||||||
@ -692,8 +931,8 @@ function UpdateSettings(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(settingNtfyEndpoint.value != "" &&
|
if(settingNtfyEndpoint.value != "" &&
|
||||||
settingNtfyAuth.value != ""){
|
settingNtfyUser.value != ""){
|
||||||
UpdateNtfy(settingNtfyEndpoint.value, settingNtfyAuth.value);
|
UpdateNtfy(settingNtfyEndpoint.value, settingNtfyUser.value, settingNtfyPass.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(settingUserAgent.value != ""){
|
if(settingUserAgent.value != ""){
|
||||||
@ -716,10 +955,6 @@ function UpdateSettings(){
|
|||||||
UpdateRateLimit(6, infoRL.value);
|
UpdateRateLimit(6, infoRL.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDexAuthorRL.value != "") {
|
|
||||||
UpdateRateLimit(5, mDexAuthorRL.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDexFeedRL.value != "") {
|
if (mDexFeedRL.value != "") {
|
||||||
UpdateRateLimit(1, mDexFeedRL.value);
|
UpdateRateLimit(1, mDexFeedRL.value);
|
||||||
}
|
}
|
||||||
@ -821,16 +1056,14 @@ function createJob(jobjson){
|
|||||||
title.innerText = manga.sortName;
|
title.innerText = manga.sortName;
|
||||||
details.appendChild(title);
|
details.appendChild(title);
|
||||||
|
|
||||||
var progressBar = document.createElement("progress");
|
var progressBarContainer = document.createElement('div');
|
||||||
progressBar.className = "jobProgressBar";
|
progressBarContainer.className = 'progress-container';
|
||||||
|
|
||||||
|
var progressBar = document.createElement("div");
|
||||||
|
progressBar.className = "pending";
|
||||||
progressBar.id = `jobProgressBar${GetValidSelector(jobjson.id)}`;
|
progressBar.id = `jobProgressBar${GetValidSelector(jobjson.id)}`;
|
||||||
details.appendChild(progressBar);
|
progressBarContainer.appendChild(progressBar);
|
||||||
|
details.appendChild(progressBarContainer);
|
||||||
var progressSpan = document.createElement("span");
|
|
||||||
progressSpan.className = "jobProgressSpan";
|
|
||||||
progressSpan.id = `jobProgressSpan${GetValidSelector(jobjson.id)}`;
|
|
||||||
progressSpan.innerText = "Pending...";
|
|
||||||
details.appendChild(progressSpan);
|
|
||||||
|
|
||||||
var cancelSpan = document.createElement("span");
|
var cancelSpan = document.createElement("span");
|
||||||
cancelSpan.className = "jobCancel";
|
cancelSpan.className = "jobCancel";
|
||||||
@ -850,18 +1083,12 @@ function ShowJobQueue(){
|
|||||||
function UpdateJobProgress(jobId){
|
function UpdateJobProgress(jobId){
|
||||||
GetProgress(jobId).then((json) => {
|
GetProgress(jobId).then((json) => {
|
||||||
var progressBar = document.querySelector(`#jobProgressBar${GetValidSelector(jobId)}`);
|
var progressBar = document.querySelector(`#jobProgressBar${GetValidSelector(jobId)}`);
|
||||||
var progressSpan = document.querySelector(`#jobProgressSpan${GetValidSelector(jobId)}`);
|
|
||||||
if(progressBar != null && json.progress != 0){
|
if(progressBar != null && json.progress != 0){
|
||||||
progressBar.value = json.progress;
|
progressBar.className = 'jobProgressBar';
|
||||||
}
|
percentageStr = Intl.NumberFormat("en-US", { style: "percent"}).format(json.progress);
|
||||||
if(progressSpan != null){
|
console.log(percentageStr);
|
||||||
var percentageStr = "0%";
|
progressBar.style.width = percentageStr;
|
||||||
var timeleftStr = "00:00:00";
|
progressBar.innerText = percentageStr;
|
||||||
if(json.progress != 0){
|
|
||||||
percentageStr = Intl.NumberFormat("en-US", { style: "percent"}).format(json.progress);
|
|
||||||
timeleftStr = json.timeRemaining.split('.')[0];
|
|
||||||
}
|
|
||||||
progressSpan.innerText = `${percentageStr} ${timeleftStr}`;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -871,7 +1098,7 @@ function GetValidSelector(str){
|
|||||||
return clean.join('');
|
return clean.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
const stringToColour = (str) => {
|
function stringToColour(str) {
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
str.split('').forEach(char => {
|
str.split('').forEach(char => {
|
||||||
hash = char.charCodeAt(0) + ((hash << 5) - hash)
|
hash = char.charCodeAt(0) + ((hash << 5) - hash)
|
||||||
|
4
Website/media/check-circle.svg
Normal file
4
Website/media/check-circle.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-check-circle" viewBox="0 0 16 16">
|
||||||
|
|
||||||
|
<path d="m10.97 4.97-.02.022-3.473 4.425-2.093-2.094a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 285 B |
3
Website/media/person.svg
Normal file
3
Website/media/person.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FFFFFF" class="bi bi-person" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10s-3.516.68-4.168 1.332c-.678.678-.83 1.418-.832 1.664z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 370 B |
@ -1,4 +1,4 @@
|
|||||||
:root{
|
:root{
|
||||||
--background-color: #030304;
|
--background-color: #030304;
|
||||||
--second-background-color: white;
|
--second-background-color: white;
|
||||||
--primary-color: #f5a9b8;
|
--primary-color: #f5a9b8;
|
||||||
@ -20,6 +20,7 @@ body{
|
|||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
font-family: "Inter", sans-serif;
|
font-family: "Inter", sans-serif;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper {
|
wrapper {
|
||||||
@ -95,10 +96,6 @@ filter-box {
|
|||||||
height: 600px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
filter-box.animate {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter-box border-bar popup-title{
|
filter-box border-bar popup-title{
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
@ -149,6 +146,10 @@ status-filter {
|
|||||||
user-select: none; /* Standard syntax */
|
user-select: none; /* Standard syntax */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
row > status-filter {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
status-filter[release-status="Ongoing"]{
|
status-filter[release-status="Ongoing"]{
|
||||||
background-color: limegreen;
|
background-color: limegreen;
|
||||||
}
|
}
|
||||||
@ -420,11 +421,14 @@ popup popup-window {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
popup#jobStatusView popup-window {
|
/*Remove below when individual chapter download is implemented*/
|
||||||
left: 20%;
|
#publicationViewerPopup > popup-window {
|
||||||
top: 20%;
|
height: fit-content;
|
||||||
height: 60%;
|
width: auto;
|
||||||
width: 60%;
|
max-width: 80%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
popup-content{
|
popup-content{
|
||||||
@ -642,66 +646,58 @@ a:active {
|
|||||||
user-select: none; /* Standard syntax */
|
user-select: none; /* Standard syntax */
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-button#reset:hover {
|
#reset:hover {
|
||||||
color: red;
|
color: rgb(255, 44, 29);
|
||||||
border-color: red;
|
border-color: rgb(255, 44, 29);
|
||||||
}
|
}
|
||||||
.section-buttons-container > .section-button:hover {
|
.section-buttons-container > .section-button:hover {
|
||||||
border-color: var(--secondary-color);
|
border-color: var(--secondary-color);
|
||||||
color: var(--secondary-color);
|
color: var(--secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#newMangaPopup > div {
|
#newMangaPopupSelector {
|
||||||
z-index: 3;
|
display: flex;
|
||||||
position: relative;
|
padding: 5px;
|
||||||
}
|
margin: 10px;
|
||||||
|
width: calc(100%-20px)
|
||||||
#newMangaPopup > #newMangaPopupSelector {
|
}
|
||||||
width: 600px;
|
|
||||||
height: 40px;
|
|
||||||
margin: 80px auto 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#newMangaPopup > div > #newMangaConnector, #newMangaTitle, #newMangaTranslatedLanguage {
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#newMangaPopup #newMangaConnector {
|
#newMangaPopup #newMangaConnector {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
padding: 0 0 0 5px;
|
padding: 5px;
|
||||||
border-radius: 5px 0 0 5px;
|
border-radius: 10px;
|
||||||
border: 0;
|
border: 0;;
|
||||||
border-right: 1px solid darkgray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#newMangaPopup #newMangaTitle{
|
#newMangaPopup #newMangaTitle{
|
||||||
width: 445px;
|
margin: 0px 10px;
|
||||||
padding: 0 5px 0 5px;
|
padding: 5px;
|
||||||
border: 0;
|
height: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-style: solid;
|
||||||
|
outline: none;
|
||||||
|
flex-grow: 1;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#newMangaPopup #newMangaTranslatedLanguage {
|
#newMangaPopup #newMangaTranslatedLanguage {
|
||||||
width: 45px;
|
width: 60px;
|
||||||
border-radius: 0 5px 5px 0;
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-left: 1px solid darkgray;
|
|
||||||
margin-left: -5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#newMangaResult {
|
#newMangaResult {
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
margin: 5px auto 0;
|
margin: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
width: min-content;
|
width: 98%;
|
||||||
max-width: 98%;
|
height: 100%;
|
||||||
max-height: 400px;
|
overflow-y: scroll;
|
||||||
overflow-x: scroll;
|
overflow-x: hidden;
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blur-background {
|
blur-background {
|
||||||
@ -719,111 +715,6 @@ blur-background {
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
publication-viewer{
|
|
||||||
display: block;
|
|
||||||
width: 460px;
|
|
||||||
position: absolute;
|
|
||||||
top: 200px;
|
|
||||||
left: 400px;
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
border-radius: 5px;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer::after{
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0; top: 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0,0,0,0.8);
|
|
||||||
backdrop-filter: blur(3px);
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer img {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 5px;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details > * {
|
|
||||||
margin: 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-name {
|
|
||||||
width: initial;
|
|
||||||
overflow-x: scroll;
|
|
||||||
white-space: nowrap;
|
|
||||||
scrollbar-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-tags::before {
|
|
||||||
content: "Tags";
|
|
||||||
display: block;
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-tags {
|
|
||||||
overflow-x: scroll;
|
|
||||||
white-space: nowrap;
|
|
||||||
scrollbar-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-author::before {
|
|
||||||
content: "Author: ";
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-description::before {
|
|
||||||
content: "Description";
|
|
||||||
display: block;
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-description {
|
|
||||||
font-size: 12pt;
|
|
||||||
margin: 5px 0;
|
|
||||||
height: 145px;
|
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-interactions {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: end;
|
|
||||||
align-items: start;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-interactions > * {
|
|
||||||
margin: 0 10px;
|
|
||||||
font-size: 16pt;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-interactions publication-starttask {
|
|
||||||
color: var(--secondary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-interactions publication-delete {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-view publication-details publication-interactions publication-canceltask {
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
publication-viewer publication-details publication-interactions publication-add {
|
|
||||||
color: limegreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer-tag-popup {
|
footer-tag-popup {
|
||||||
display: none;
|
display: none;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
@ -886,6 +777,10 @@ footer-tag-popup::before{
|
|||||||
z-index: 201;
|
z-index: 201;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popup-content #loaderdiv {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#loaderText {
|
#loaderText {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@ -915,6 +810,169 @@ footer-tag-popup::before{
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#newMangaResult > .section-item {
|
||||||
|
flex-direction: row;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img-container {
|
||||||
|
height: 300px;
|
||||||
|
width: 180px;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img-container > img {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
z-index: 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-connector {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
/*Text Properties*/
|
||||||
|
font-size:8pt;
|
||||||
|
font-weight:bold;
|
||||||
|
color:white;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-details > .mangaDescription {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-chapter {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px;
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-color: #bbb;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--secondary-color) var(--second-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
chapter-row {
|
||||||
|
font-size: 12pt;
|
||||||
|
width: 100%;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #ccc;
|
||||||
|
border-width: 1px;
|
||||||
|
padding-left: 50px;
|
||||||
|
padding-top: 7px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.latest-chapter-no {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
padding: 5px 10px 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
background-color: var(--primary-color);;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.new-manga-download-settings {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
width: calc(100%-20px);
|
||||||
|
height: auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-manga-download-settings > row {
|
||||||
|
width: 80%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-manga-download-settings > row > label {
|
||||||
|
text-wrap: nowrap;
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #474646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-manga-download-settings > row > input {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: lightgray;
|
||||||
|
outline: none;
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.new-manga-download-settings > row > input:focus {
|
||||||
|
border-color: var(--secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
/* For mobile phones: */
|
||||||
|
img-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-item > tag-cloud {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.new-manga-download-settings > row, .downloadManga, border-bar-button.in-library {
|
||||||
|
width: calc(100% - 25px) !important;
|
||||||
|
align-self: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
popup popup-window {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - var(--topbar-height));
|
||||||
|
top: var(--topbar-height);
|
||||||
|
left: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-item {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.section-item > .jobImage {
|
.section-item > .jobImage {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: auto;
|
width: auto;
|
||||||
@ -927,7 +985,9 @@ footer-tag-popup::before{
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: calc(100% - 15px);
|
||||||
|
margin-left: 7px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-item > .jobDetails > .jobTitle {
|
.section-item > .jobDetails > .jobTitle {
|
||||||
@ -937,16 +997,189 @@ footer-tag-popup::before{
|
|||||||
text-wrap: wrap;
|
text-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-item > .jobDetails > .jobProgressBar {
|
header-row {
|
||||||
margin: 5px;
|
display: flex;
|
||||||
height: 10px;
|
flex-direction: row;
|
||||||
border-radius: 7px;
|
width: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-item > .jobDetails > .jobProgressSpan {
|
.mangaTitle {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
margin-left: auto;
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
text-wrap: wrap;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag-cloud {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-left: 10px;
|
||||||
|
width: calc(100% - 30px);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-tag {
|
||||||
|
display: inline-block;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
position: relative;
|
||||||
|
margin: 0 5px 8px 17px;
|
||||||
|
padding: 0 10px 0 12px;
|
||||||
|
background: darkslategrey;
|
||||||
|
-webkit-border-bottom-right-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
-webkit-border-top-right-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 11px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-tag:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
left: -12px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-color: transparent darkslategrey transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 12px 12px 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
manga-tag:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 1px;
|
||||||
|
float: left;
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
-webkit-border-radius: 50%;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
author-tag {
|
||||||
|
display: inline-block;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 0px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
background: #800000;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 11px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
author-tag > img {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
float: left;
|
||||||
|
background: #800000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mangaDescription {
|
||||||
|
font-size: 10pt;
|
||||||
|
padding: 4px;
|
||||||
|
height: auto;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abbreviated {
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 10;
|
||||||
|
line-clamp: 10;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadManga {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
width: fit-content;
|
||||||
|
margin: 5px 5px 0 auto;
|
||||||
|
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
border-bar-button.in-library {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
margin: 5px 5px 0 auto;
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 10pt;
|
||||||
|
|
||||||
|
background-color: #08962e;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
border-bar-button.in-library:hover {
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-item > .jobDetails > .progress-container {
|
||||||
|
margin: 5px;
|
||||||
|
height: 15px;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #999999;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-container > .jobProgressBar {
|
||||||
|
margin: 0px;
|
||||||
|
display: block;
|
||||||
|
height: 15px;
|
||||||
|
padding-left: 5px;
|
||||||
|
border-radius: 12px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background-color: #0075fa;
|
||||||
|
color: white;
|
||||||
|
justify-content: left;
|
||||||
|
font-size: 8pt;
|
||||||
|
line-height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-container > .pending {
|
||||||
|
width: 50%;
|
||||||
|
display: block;
|
||||||
|
height: 15px;
|
||||||
|
top: 0%;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #0075fa;
|
||||||
|
animation: bounce;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
0% {width: 10%; transform: translateX(0);};
|
||||||
|
50% {width: 50%; transform: translateX(100%);};
|
||||||
|
100% {width: 10%; transform: translateX(0);};
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-item > .jobDetails > .jobCancel {
|
.section-item > .jobDetails > .jobCancel {
|
||||||
@ -957,4 +1190,62 @@ footer-tag-popup::before{
|
|||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
color: var(--secondary-color);
|
color: var(--secondary-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The switch - the box around the slider */
|
||||||
|
.switch-toggle {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: auto;
|
||||||
|
float: right;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide default HTML checkbox */
|
||||||
|
.switch-toggle input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The slider */
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s; border-radius: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus + .slider {
|
||||||
|
box-shadow: 0 0 1px var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider:before {
|
||||||
|
-webkit-transform: translateX(20px);
|
||||||
|
-ms-transform: translateX(20px);
|
||||||
|
transform: translateX(20px);
|
||||||
|
}
|
26
nginx/fastcgi.conf
Normal file
26
nginx/fastcgi.conf
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param QUERY_STRING $query_string;
|
||||||
|
fastcgi_param REQUEST_METHOD $request_method;
|
||||||
|
fastcgi_param CONTENT_TYPE $content_type;
|
||||||
|
fastcgi_param CONTENT_LENGTH $content_length;
|
||||||
|
|
||||||
|
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||||
|
fastcgi_param REQUEST_URI $request_uri;
|
||||||
|
fastcgi_param DOCUMENT_URI $document_uri;
|
||||||
|
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||||
|
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
|
fastcgi_param REQUEST_SCHEME $scheme;
|
||||||
|
fastcgi_param HTTPS $https if_not_empty;
|
||||||
|
|
||||||
|
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||||
|
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||||
|
|
||||||
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
fastcgi_param REMOTE_PORT $remote_port;
|
||||||
|
fastcgi_param SERVER_ADDR $server_addr;
|
||||||
|
fastcgi_param SERVER_PORT $server_port;
|
||||||
|
fastcgi_param SERVER_NAME $server_name;
|
||||||
|
|
||||||
|
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||||
|
fastcgi_param REDIRECT_STATUS 200;
|
25
nginx/fastcgi_params
Normal file
25
nginx/fastcgi_params
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
fastcgi_param QUERY_STRING $query_string;
|
||||||
|
fastcgi_param REQUEST_METHOD $request_method;
|
||||||
|
fastcgi_param CONTENT_TYPE $content_type;
|
||||||
|
fastcgi_param CONTENT_LENGTH $content_length;
|
||||||
|
|
||||||
|
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||||
|
fastcgi_param REQUEST_URI $request_uri;
|
||||||
|
fastcgi_param DOCUMENT_URI $document_uri;
|
||||||
|
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||||
|
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
|
fastcgi_param REQUEST_SCHEME $scheme;
|
||||||
|
fastcgi_param HTTPS $https if_not_empty;
|
||||||
|
|
||||||
|
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||||
|
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||||
|
|
||||||
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
fastcgi_param REMOTE_PORT $remote_port;
|
||||||
|
fastcgi_param SERVER_ADDR $server_addr;
|
||||||
|
fastcgi_param SERVER_PORT $server_port;
|
||||||
|
fastcgi_param SERVER_NAME $server_name;
|
||||||
|
|
||||||
|
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||||
|
fastcgi_param REDIRECT_STATUS 200
|
99
nginx/mimes.types
Normal file
99
nginx/mimes.types
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
types {
|
||||||
|
text/html html htm shtml;
|
||||||
|
text/css css;
|
||||||
|
text/xml xml;
|
||||||
|
image/gif gif;
|
||||||
|
image/jpeg jpeg jpg;
|
||||||
|
application/javascript js;
|
||||||
|
application/atom+xml atom;
|
||||||
|
application/rss+xml rss;
|
||||||
|
|
||||||
|
text/mathml mml;
|
||||||
|
text/plain txt;
|
||||||
|
text/vnd.sun.j2me.app-descriptor jad;
|
||||||
|
text/vnd.wap.wml wml;
|
||||||
|
text/x-component htc;
|
||||||
|
|
||||||
|
image/avif avif;
|
||||||
|
image/png png;
|
||||||
|
image/svg+xml svg svgz;
|
||||||
|
image/tiff tif tiff;
|
||||||
|
image/vnd.wap.wbmp wbmp;
|
||||||
|
image/webp webp;
|
||||||
|
image/x-icon ico;
|
||||||
|
image/x-jng jng;
|
||||||
|
image/x-ms-bmp bmp;
|
||||||
|
|
||||||
|
font/woff woff;
|
||||||
|
font/woff2 woff2;
|
||||||
|
|
||||||
|
application/java-archive jar war ear;
|
||||||
|
application/json json;
|
||||||
|
application/mac-binhex40 hqx;
|
||||||
|
application/msword doc;
|
||||||
|
application/pdf pdf;
|
||||||
|
application/postscript ps eps ai;
|
||||||
|
application/rtf rtf;
|
||||||
|
application/vnd.apple.mpegurl m3u8;
|
||||||
|
application/vnd.google-earth.kml+xml kml;
|
||||||
|
application/vnd.google-earth.kmz kmz;
|
||||||
|
application/vnd.ms-excel xls;
|
||||||
|
application/vnd.ms-fontobject eot;
|
||||||
|
application/vnd.ms-powerpoint ppt;
|
||||||
|
application/vnd.oasis.opendocument.graphics odg;
|
||||||
|
application/vnd.oasis.opendocument.presentation odp;
|
||||||
|
application/vnd.oasis.opendocument.spreadsheet ods;
|
||||||
|
application/vnd.oasis.opendocument.text odt;
|
||||||
|
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
||||||
|
pptx;
|
||||||
|
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||||
|
xlsx;
|
||||||
|
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||||
|
docx;
|
||||||
|
application/vnd.wap.wmlc wmlc;
|
||||||
|
application/wasm wasm;
|
||||||
|
application/x-7z-compressed 7z;
|
||||||
|
application/x-cocoa cco;
|
||||||
|
application/x-java-archive-diff jardiff;
|
||||||
|
application/x-java-jnlp-file jnlp;
|
||||||
|
application/x-makeself run;
|
||||||
|
application/x-perl pl pm;
|
||||||
|
application/x-pilot prc pdb;
|
||||||
|
application/x-rar-compressed rar;
|
||||||
|
application/x-redhat-package-manager rpm;
|
||||||
|
application/x-sea sea;
|
||||||
|
application/x-shockwave-flash swf;
|
||||||
|
application/x-stuffit sit;
|
||||||
|
application/x-tcl tcl tk;
|
||||||
|
application/x-x509-ca-cert der pem crt;
|
||||||
|
application/x-xpinstall xpi;
|
||||||
|
application/xhtml+xml xhtml;
|
||||||
|
application/xspf+xml xspf;
|
||||||
|
application/zip zip;
|
||||||
|
|
||||||
|
application/octet-stream bin exe dll;
|
||||||
|
application/octet-stream deb;
|
||||||
|
application/octet-stream dmg;
|
||||||
|
application/octet-stream iso img;
|
||||||
|
application/octet-stream msi msp msm;
|
||||||
|
|
||||||
|
audio/midi mid midi kar;
|
||||||
|
audio/mpeg mp3;
|
||||||
|
audio/ogg ogg;
|
||||||
|
audio/x-m4a m4a;
|
||||||
|
audio/x-realaudio ra;
|
||||||
|
|
||||||
|
video/3gpp 3gpp 3gp;
|
||||||
|
video/mp2t ts;
|
||||||
|
video/mp4 mp4;
|
||||||
|
video/mpeg mpeg mpg;
|
||||||
|
video/quicktime mov;
|
||||||
|
video/webm webm;
|
||||||
|
video/x-flv flv;
|
||||||
|
video/x-m4v m4v;
|
||||||
|
video/x-mng mng;
|
||||||
|
video/x-ms-asf asx asf;
|
||||||
|
video/x-ms-wmv wmv;
|
||||||
|
video/x-msvideo avi;
|
||||||
|
}
|
32
nginx/nginx.conf
Normal file
32
nginx/nginx.conf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log notice;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
#tcp_nopush on;
|
||||||
|
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
#gzip on;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
17
nginx/scgi_params
Normal file
17
nginx/scgi_params
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
scgi_param REQUEST_METHOD $request_method;
|
||||||
|
scgi_param REQUEST_URI $request_uri;
|
||||||
|
scgi_param QUERY_STRING $query_string;
|
||||||
|
scgi_param CONTENT_TYPE $content_type;
|
||||||
|
|
||||||
|
scgi_param DOCUMENT_URI $document_uri;
|
||||||
|
scgi_param DOCUMENT_ROOT $document_root;
|
||||||
|
scgi_param SCGI 1;
|
||||||
|
scgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
|
scgi_param REQUEST_SCHEME $scheme;
|
||||||
|
scgi_param HTTPS $https if_not_empty;
|
||||||
|
|
||||||
|
scgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
scgi_param REMOTE_PORT $remote_port;
|
||||||
|
scgi_param SERVER_PORT $server_port;
|
||||||
|
scgi_param SERVER_NAME $server_name;
|
29
nginx/templates/default.conf.template
Normal file
29
nginx/templates/default.conf.template
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
http2 on;
|
||||||
|
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
access_log /dev/stdout main;
|
||||||
|
error_log /dev/stderr;
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass_request_headers on;
|
||||||
|
rewrite ^/api/(.*)$ /$1 break;
|
||||||
|
proxy_pass $API_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
|
||||||
|
# redirect server error pages to the static page /50x.html
|
||||||
|
#
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
17
nginx/uwsgi_params
Normal file
17
nginx/uwsgi_params
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
uwsgi_param QUERY_STRING $query_string;
|
||||||
|
uwsgi_param REQUEST_METHOD $request_method;
|
||||||
|
uwsgi_param CONTENT_TYPE $content_type;
|
||||||
|
uwsgi_param CONTENT_LENGTH $content_length;
|
||||||
|
|
||||||
|
uwsgi_param REQUEST_URI $request_uri;
|
||||||
|
uwsgi_param PATH_INFO $document_uri;
|
||||||
|
uwsgi_param DOCUMENT_ROOT $document_root;
|
||||||
|
uwsgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
|
uwsgi_param REQUEST_SCHEME $scheme;
|
||||||
|
uwsgi_param HTTPS $https if_not_empty;
|
||||||
|
|
||||||
|
uwsgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
uwsgi_param REMOTE_PORT $remote_port;
|
||||||
|
uwsgi_param SERVER_PORT $server_port;
|
||||||
|
uwsgi_param SERVER_NAME $server_name;
|
Loading…
Reference in New Issue
Block a user