Compare commits

...

17 Commits

Author SHA1 Message Date
6fac397e36
Merge pull request #41 from db-2001/settings-rework
Settings rework with Filter changes
2024-02-28 03:22:44 +01:00
db-2001
5cda6ece05 Potential fix/support for HTTPS
Removed the hard-coded http in the API url and instead calling  window.location.protocol
2024-02-24 10:27:14 -05:00
db-2001
b99ade74c7 Commented out console logging of logs 2024-02-11 18:41:21 -05:00
db-2001
4f6b07280a Finalized Downlolad Logs button
B)
2024-02-11 18:39:27 -05:00
db-2001
01067006f8 Commenting out console logging of HTTP request response 2024-02-11 17:01:37 -05:00
db-2001
4c418add81 Updates to match API 2024-02-11 16:59:05 -05:00
db-2001
1ee17360e5 Small visual tweak to make the user agent the textbox value rather than placeholder
Allows for the user to make small changes to API URI and user agent if needed, previous method would have required re-typing in the entire string with is a PITA.
2024-02-10 13:54:24 -05:00
db-2001
9accca0ad2 Applied new popup style to Jobs view and fixed manga library populating twice sometimes 2024-02-10 13:49:51 -05:00
db-2001
9309a4e28f Potential fix for preventing the filter buttons from loading multiple times 2024-02-10 11:56:19 -05:00
db-2001
c75f65f3d5 Remove redundant refresh library 2024-02-09 11:20:09 -05:00
db-2001
c7e49fb6bc Added in remaining Tranga settings functionality
Changed CSS style to be stored in local storage since we might want it to be browser specific (mobile vs desktop vs tablet)
2024-02-09 11:17:33 -05:00
db-2001
2c5a032890 Added rate limits to UpdateSettings 2024-02-08 23:56:31 -05:00
db-2001
8bd6ad4c2b Added manga sources to settings
Added the manga sources to the settings page and added a field to set the rate limit, POST api for setting the rate limit awaiting GET api calls to set initial value.
2024-02-08 23:31:31 -05:00
db-2001
148af6abaa Filter functionality
Removed textbox in top bar and added filter icon that opens up a box where you can search or select a connector/status and combination to filter by. Appearance and behavior needs to be refined.
2024-02-06 22:23:19 -05:00
db-2001
1ba49ddf08 Added PostData to reset functions 2024-02-04 16:02:09 -05:00
db-2001
f50990dafb Reimplemented Library and Notification connectors
Added Test and Rest API calls, API side will need to be updated.

Separated out CSS files for future expansion.
2024-02-04 15:47:13 -05:00
db-2001
76f6216501 Initial commit
Resized settings pop-up and fixed scrollable behavior, broke everything inside pop-up (on purpose)
2024-02-03 00:41:12 -05:00
21 changed files with 1709 additions and 1162 deletions

7
.gitignore vendored
View File

@ -18,4 +18,9 @@ riderModule.iml
/dataSources.local.xml
/.idea
cover.jpg
cover.png
cover.png
.vs/slnx.sqlite
.vs/tranga-website/config/applicationhost.config
.vs/tranga-website/FileContentIndex/91a465d3-1190-42e0-95eb-fa3694744e58.vsidx
.vs/tranga-website/v17/.wsuo
.vs/VSWorkspaceState.json

View File

@ -1,4 +1,4 @@
let apiUri = `http://${window.location.host.split(':')[0]}:6531`
let apiUri = `${window.location.protocol}//${window.location.host.split(':')[0]}:6531`
if(getCookie("apiUri") != ""){
apiUri = getCookie("apiUri");
@ -39,10 +39,11 @@ async function GetData(uri){
return json;
}
function PostData(uri){
fetch(uri, {
async function PostData(uri){
let request = await fetch(uri, {
method: 'POST'
});
//console.log(request);
}
function DeleteData(uri){
@ -143,6 +144,12 @@ async function GetLibraryConnectors(){
return json;
}
async function GetRateLimits() {
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);
@ -163,46 +170,164 @@ function UpdateDownloadLocation(downloadLocation){
PostData(uri);
}
function ChangeStyleSheet(sheet){
var uri = `${apiUri}/Settings/ChangeStyleSheet?styleSheet=${sheet}`;
PostData(uri);
}
function RefreshLibraryMetadata() {
var uri = `${apiUri}/Jobs/UpdateMetadata`;
PostData(uri);
}
async function DownloadLogs() {
var uri = `${apiUri}/LogFile`;
//Below taken from https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
fetch(uri)
.then((response) => response.body)
.then((rb) => {
const reader = rb.getReader();
return new ReadableStream({
start(controller) {
// The following function handles each data chunk
function push() {
// "done" is a Boolean and value a "Uint8Array"
reader.read().then(({ done, value }) => {
// If there is no more data to read
if (done) {
console.log("done", done);
controller.close();
return;
}
// Get the data and send it to the browser via the controller
controller.enqueue(value);
// Check chunks by logging to the console
console.log(done, value);
push();
});
}
push();
},
});
})
.then((stream) =>
// Respond with our stream
new Response(stream, { headers: { "Content-Type": "text/html" } }).text(),
)
.then((result) => {
// Do things with result
//console.log(result);
//Below download taken from https://stackoverflow.com/questions/3665115/how-to-create-a-file-in-memory-for-user-to-download-but-not-through-server
var element = document.createElement('a');
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);
element.click();
});
}
//Following date-time code taken from: https://stackoverflow.com/questions/10211145/getting-current-date-and-time-in-javascript
// For todays date;
Date.prototype.today = function () {
return ((this.getDate() < 10)?"0":"") + this.getDate() +"/"+(((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ this.getFullYear();
}
// For the time now
Date.prototype.timeNow = function () {
return ((this.getHours() < 10)?"0":"") + this.getHours() +"_"+ ((this.getMinutes() < 10)?"0":"") + this.getMinutes() +"_"+ ((this.getSeconds() < 10)?"0":"") + this.getSeconds();
}
//Komga
function UpdateKomga(komgaUrl, komgaAuth){
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
PostData(uri);
}
function ResetKomga(){
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Komga`;
PostData(uri);
}
function TestKomga(komgaUrl, komgaAuth){
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Komga&komgaUrl=${komgaUrl}&komgaAuth=${komgaAuth}`;
PostData(uri);
}
//Kavita
function UpdateKavita(kavitaUrl, kavitaUsername, kavitaPassword){
var uri = `${apiUri}/LibraryConnectors/Update?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
PostData(uri);
}
function ResetKavita(){
var uri = `${apiUri}/LibraryConnectors/Reset?libraryConnector=Kavita`;
PostData(uri);
}
function TestKavita(kavitaUrl, kavitaUsername, kavitaPassword){
var uri = `${apiUri}/LibraryConnectors/Test?libraryConnector=Kavita&kavitaUrl=${kavitaUrl}&kavitaUsername=${kavitaUsername}&kavitaPassword=${kavitaPassword}`;
PostData(uri);
}
//Gotify
function UpdateGotify(gotifyUrl, gotifyAppToken){
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
PostData(uri);
}
function ResetGotify(){
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Gotify`;
PostData(uri);
}
function TestGotify(gotifyUrl, gotifyAppToken){
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Gotify&gotifyUrl=${gotifyUrl}&gotifyAppToken=${gotifyAppToken}`;
PostData(uri);
}
//LunaSea
function UpdateLunaSea(lunaseaWebhook){
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
PostData(uri);
}
function ResetLunaSea(){
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=LunaSea`;
PostData(uri);
}
function TestLunaSea(lunaseaWebhook){
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=LunaSea&lunaseaWebhook=${lunaseaWebhook}`;
PostData(uri);
}
//Ntfy
function UpdateNtfy(ntfyEndpoint, ntfyAuth){
var uri = `${apiUri}/NotificationConnectors/Update?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyAuth=${ntfyAuth}`;
PostData(uri);
}
function ResetNtfy(){
var uri = `${apiUri}/NotificationConnectors/Reset?notificationConnector=Ntfy`;
PostData(uri);
}
function TestNtfy(ntfyEndpoint, ntfyAuth){
var uri = `${apiUri}/NotificationConnectors/Test?notificationConnector=Ntfy&ntfyUrl=${ntfyEndpoint}&ntfyAuth=${ntfyAuth}`;
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);
@ -216,5 +341,6 @@ function CancelJob(jobId){
async function GetLogmessages(count){
var uri = `${apiUri}/LogMessages?count=${count}`;
let json = await GetData(uri);
console.log(json);
return json;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="512pt"
viewBox="0 0 512 512"
width="512pt"
version="1.1"
id="svg4586"
sodipodi:docname="komga - Copy.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata4592">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4590">
<linearGradient
id="linearGradient6082"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop6080"/>
</linearGradient>
<linearGradient
id="linearGradient6076"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop6074"/>
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6082"
id="linearGradient6084"
x1="77.866812"
y1="386.00679"
x2="217.20259"
y2="386.00679"
gradientUnits="userSpaceOnUse"/>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1656"
inkscape:window-height="1368"
id="namedview4588"
showgrid="false"
inkscape:zoom="1.2512475"
inkscape:cx="264.73114"
inkscape:cy="305.20589"
inkscape:window-x="-7"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg4586"/>
<path
d="m512 256c0 141.386719-114.613281 256-256 256s-256-114.613281-256-256 114.613281-256 256-256 256 114.613281 256 256zm0 0"
fill="#005ed3"
id="path4556"/>
<path
d="m 512,256 c 0,-11.71094 -0.80469,-23.23047 -2.32422,-34.52344 L 382.48047,94.28125 320.52344,121.85938 256,56.933594 212.69531,131.30469 129.51953,94.28125 141.86719,178.42187 49.949219,193.81641 114.32031,256 l -64.371091,62.18359 82.121091,82.16016 -2.55078,17.375 91.95703,91.95703 C 232.76953,511.19531 244.28906,512 256,512 397.38672,512 512,397.38672 512,256 Z"
id="path4558"
inkscape:connector-curvature="0"
style="fill:#00459f"
sodipodi:nodetypes="scccccccccccccss"/>
<path
d="m256 86.742188 37.109375 63.738281 70.574219-31.414063-10.527344 71.71875 77.078125 12.910156-54.144531 52.304688 54.144531 52.304688-77.078125 12.910156 10.527344 71.71875-70.574219-31.414063-37.109375 63.738281-37.109375-63.738281-70.574219 31.414063 10.527344-71.71875-77.078125-12.910156 54.144531-52.304688-54.144531-52.304688 77.078125-12.910156-10.527344-71.71875 70.574219 31.414063zm0 0"
fill="#ff0335"
id="path4560"/>
<path
d="m430.230469 308.300781-77.070313 12.910157 10.519532 71.71875-70.570313-31.410157-37.109375 63.742188v-338.523438l37.109375 63.742188 70.570313-31.410157-6.757813 46.101563-3.761719 25.617187 58.800782 9.851563 18.269531 3.058594-13.390625 12.929687-40.75 39.371094 11.378906 10.988281zm0 0"
fill="#c2001b"
id="path4562"/>
<path
d="m256 455.066406-43.304688-74.371094-83.175781 37.023438 12.347657-84.140625-91.917969-15.394531 64.371093-62.183594-64.371093-62.183594 91.917969-15.394531-12.347657-84.140625 83.179688 37.023438 43.300781-74.371094 43.304688 74.371094 83.175781-37.023438-12.347657 84.140625 91.917969 15.394531-64.371093 62.183594 64.371093 62.183594-91.917969 15.398437 12.347657 84.136719-83.175781-37.023438zm-30.917969-112.722656 30.917969 53.101562 30.917969-53.101562 57.964843 25.800781-8.703124-59.292969 62.238281-10.425781-43.917969-42.425781 43.917969-42.425781-62.238281-10.425781 8.703124-59.292969-57.964843 25.800781-30.917969-53.101562-30.917969 53.101562-57.964843-25.800781 8.703124 59.292969-62.238281 10.425781 43.917969 42.425781-43.917969 42.425781 62.238281 10.425781-8.703124 59.292969zm0 0"
fill="#ffdf47"
id="path4564"/>
<path
d="m403.308594 261.441406-5.628906-5.441406 25.160156-24.300781 39.210937-37.878907-55.75-9.339843-36.171875-6.058594 2.800782-19.09375 9.550781-65.046875-83.179688 37.019531-43.300781-74.371093v59.621093l30.921875 53.109375 57.957031-25.808594-3.910156 26.667969-2.546875 17.378907-2.242187 15.25 2.480468.421874 59.761719 10.007813-43.921875 42.421875 16.96875 16.390625 26.953125 26.03125-62.242187 10.429687 8.699218 59.296876-57.957031-25.808594-30.921875 53.109375v59.621093l43.300781-74.371093 83.179688 37.019531-12.351563-84.140625 91.921875-15.398437zm0 0"
fill="#fec000"
id="path4566"/>
<g
aria-label="K"
transform="matrix(1.1590846,-0.34467221,0.22789693,0.794981,0,0)"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:296.55969238px;line-height:125%;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.54528999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="text4596">
<path
d="m 220.91497,266.9035 -34.89789,105.85211 38.2284,128.58643 H 161.2555 L 136.63873,400.84769 V 501.34204 H 75.676021 V 266.9035 h 60.962709 v 91.08205 l 27.07845,-91.08205 z"
style="font-size:296.55969238px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.54528999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path824"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,40 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50mm" height="50mm" viewBox="0 0 50 50">
<defs>
<linearGradient id="b">
<stop offset="0" style="stop-color:#348878;stop-opacity:1"/>
<stop offset="1" style="stop-color:#52bca6;stop-opacity:1"/>
</linearGradient>
<linearGradient id="a">
<stop offset="0" style="stop-color:#348878;stop-opacity:1"/>
<stop offset="1" style="stop-color:#56bda8;stop-opacity:1"/>
</linearGradient>
<linearGradient xlink:href="#a" id="e" x1="160.722" x2="168.412" y1="128.533" y2="134.326" gradientTransform="matrix(3.74959 0 0 3.74959 -541.79 -387.599)" gradientUnits="userSpaceOnUse"/>
<linearGradient xlink:href="#b" id="c" x1=".034" x2="50.319" y1="0" y2="50.285" gradientTransform="matrix(.99434 0 0 .99434 -.034 0)" gradientUnits="userSpaceOnUse"/>
<filter id="d" width="1.176" height="1.211" x="-.076" y="-.092" style="color-interpolation-filters:sRGB">
<feFlood flood-color="#fff" flood-opacity=".192" result="flood"/>
<feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
<feGaussianBlur in="composite1" result="blur" stdDeviation="4"/>
<feOffset dx="3" dy="2.954" result="offset"/>
<feComposite in="SourceGraphic" in2="offset" result="composite2"/>
</filter>
</defs>
<g style="display:inline">
<path d="M0 0h50v50H0z" style="fill:url(#c);fill-opacity:1;stroke:none;stroke-width:.286502;stroke-linejoin:bevel"/>
</g>
<g style="display:inline">
<path d="M50.4 46.883c-9.168 0-17.023 7.214-17.023 16.387v.007l.09 71.37-2.303 16.992 31.313-8.319h77.841c9.17 0 17.024-7.224 17.024-16.396V63.27c0-9.17-7.85-16.383-17.016-16.387h-.008zm0 11.566h89.926c3.222.004 5.45 2.347 5.45 4.82v63.655c0 2.475-2.232 4.82-5.457 4.82h-79.54l-15.908 4.807.162-.938-.088-72.343c0-2.476 2.23-4.82 5.455-4.82z" style="color:#fff;display:inline;fill:#fff;stroke:none;stroke-width:1.93113;-inkscape-stroke:none;filter:url(#d)" transform="scale(.26458)"/>
</g>
<g style="display:inline">
<path d="M88.2 95.309H64.92c-1.601 0-2.91 1.236-2.91 2.746l.022 18.602-.435 2.506 6.231-1.881H88.2c1.6 0 2.91-1.236 2.91-2.747v-16.48c0-1.51-1.31-2.746-2.91-2.746z" style="color:#fff;fill:url(#e);stroke:none;stroke-width:2.49558;-inkscape-stroke:none" transform="translate(-51.147 -81.516)"/>
<path d="M50.4 46.883c-9.168 0-17.023 7.214-17.023 16.387v.007l.09 71.37-2.303 16.992 31.313-8.319h77.841c9.17 0 17.024-7.224 17.024-16.396V63.27c0-9.17-7.85-16.383-17.016-16.387h-.008zm0 11.566h89.926c3.222.004 5.45 2.347 5.45 4.82v63.655c0 2.475-2.232 4.82-5.457 4.82h-79.54l-15.908 4.807.162-.938-.088-72.343c0-2.476 2.23-4.82 5.455-4.82z" style="color:#fff;fill:#fff;stroke:none;stroke-width:1.93113;-inkscape-stroke:none" transform="scale(.26458)"/>
<g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#fff;stroke:none;stroke-width:.525121">
<path d="M62.57 116.77v-1.312l3.28-1.459q.159-.068.306-.102.158-.045.283-.068l.271-.022v-.09q-.136-.012-.271-.046-.125-.023-.283-.057-.147-.045-.306-.113l-3.28-1.459v-1.323l5.068 2.319v1.413z" style="color:#fff;-inkscape-font-specification:&quot;JetBrains Mono, Bold&quot;;fill:#fff;stroke:none;-inkscape-stroke:none" transform="matrix(1.45366 0 0 1.72815 -75.122 -171.953)"/>
<path d="M62.309 110.31v1.903l3.437 1.53.022.007-.022.008-3.437 1.53v1.892l.37-.17 5.221-2.39v-1.75zm.525.817 4.541 2.08v1.076l-4.541 2.078v-.732l3.12-1.389.003-.002a1.56 1.56 0 0 1 .258-.086h.006l.008-.002c.094-.027.176-.047.246-.06l.498-.041v-.574l-.24-.02a1.411 1.411 0 0 1-.231-.04l-.008-.001-.008-.002a9.077 9.077 0 0 1-.263-.053 2.781 2.781 0 0 1-.266-.097l-.004-.002-3.119-1.39z"
style="color:#fff;-inkscape-font-specification:&quot;JetBrains Mono, Bold&quot;;fill:#fff;stroke:none;-inkscape-stroke:none" transform="matrix(1.45366 0 0 1.72815 -75.122 -171.953)"/>
</g>
<g style="font-size:8.48274px;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill:#fff;stroke:none;stroke-width:.525121">
<path d="M69.171 117.754h5.43v1.278h-5.43Z" style="color:#fff;-inkscape-font-specification:&quot;JetBrains Mono, Bold&quot;;fill:#fff;stroke:none;-inkscape-stroke:none" transform="matrix(1.44935 0 0 1.66414 -74.104 -166.906)"/>
<path d="M68.908 117.492v1.802h5.955v-1.802zm.526.524h4.904v.754h-4.904z" style="color:#fff;-inkscape-font-specification:&quot;JetBrains Mono, Bold&quot;;fill:#fff;stroke:none;-inkscape-stroke:none" transform="matrix(1.44935 0 0 1.66414 -74.104 -166.906)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -3,22 +3,50 @@
<head>
<meta charset="UTF-8">
<title>Tranga</title>
<link id='pagestyle' rel="stylesheet" href="styles/style_default.css">
<link id='basestyle' rel="stylesheet" href="styles/base.css">
<link id='librarystyle' rel="stylesheet" href="styles/style_default.css">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<wrapper>
<topbar>
<titlebox>
<img alt="website image is Blahaj" src="media/blahaj.png">
<span>Tranga</span>
</titlebox>
<spacer></spacer>
<searchdiv>
<label for="searchbox"></label><input id="searchbox" placeholder="Filter" type="text">
</searchdiv>
<img id="filterFunnel" src="media/filter-funnel.svg" height="50%" alt="filterFunnel">
<img id="settingscog" src="media/settings-cogwheel.svg" height="100%" alt="settingscog">
</topbar>
<filter-box id="filterBox">
<border-bar>
<popup-title>Filter by: </popup-title>
<popup-close onclick="filterBox.classList.toggle('animate')" >&times</popup-close>
</border-bar>
<popup-content id="filterContent">
<div class="popup-section">
NAME:
<div class="section-content">
<label for="searchbox"></label><input id="searchbox" placeholder="Title" type="text">
</div>
</div>
<div class = "popup-section">
CONNECTOR:
<div class="section-content" id="connectorFilterBox">
</div>
</div>
<div class = "popup-section">
STATUS:
<div class="section-content" id="statusFilterBox">
</div>
</div>
</popup-content>
<border-bar-button onclick="ClearFilter()" class="clearFilter">Clear Filter</border-bar-button>
</filter-box>
<viewport>
<div id="loaderdiv">
<blur-background></blur-background>
@ -53,65 +81,150 @@
</popup>
<popup id="settingsPopup">
<blur-background id="blurBackgroundSettingsPopup" onclick="
settingsPopup.style.display = 'none';"></blur-background>
<blur-background id="blurBackgroundSettingsPopup" onclick="settingsPopup.style.display = 'none';"></blur-background>
<popup-window>
<popup-title>Settings</popup-title>
<border-bar>
<popup-title>Settings</popup-title>
<popup-close onclick="settingsPopup.style.display = 'none'">&times</popup-close>
</border-bar>
<popup-content>
<div>
<p class="title">Download Location:</p>
<span id="downloadLocation"></span>
<div class="popup-section">
TRANGA
<div class="section-content">
<div class="section-item dyn-height">
<span class="title">API Settings</span>
<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>
<border-bar-button class="section" onclick="RefreshLibraryMetadata()">Refresh Library Metadata</border-bar-button>
<border-bar-button class="section" onclick="DownloadLogs()">Download Logs</border-bar-button>
</row>
</div>
<div class="section-item dyn-height">
<span class="title">Rate Limits</span>
<row><label for="DefaultRL">Default:</label><input id="defaultRL" 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="InfoRL">Manga Info:</label><input id="infoRL" type="text"></row>
</div>
<div class="section-item dyn-height">
<span class="title">Appearance</span>
<row><label for="cssStyle">Library Style:</label><select id="cssStyle">
<option id="card_compact" value="card_compact">Cards (Compact)</option>
<option id="card_hover" value="card_hover">Cards (Hover)</option>
</select></row>
</div>
</div>
</div>
<div>
<p class="title">API-URI</p>
<label for="settingApiUri"></label><input placeholder="https://" type="text" id="settingApiUri">
<div class="popup-section">
MANGA SOURCES
<div class="section-content">
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/manganato.png"><a href="https://manganato.com">MangaNato</a></span>
</div> -->
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/mangasee.png"><a href="https://mangasee123.com">MangaSee</a></span>
</div> -->
<div class="section-item dyn-height">
<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="mDexImageRL">Image Rate Limit:</label><input id="mDexImageRL" type="text"></row>
</div>
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/mangakatana.png"><a href="https://mangakatana.com">MangaKatana</a></span>
</div> -->
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/mangaworld.png"><a href="https://www.mangaworld.ac">MangaWorld</a></span>
</div> -->
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/bato.ico"><a href="https://bato.to">Bato</a></span>
</div> -->
<!-- <div class="section-item dyn-height">
<span class="title"><img src="connector-icons/mangalife.png"><a href="https://www.manga4life.com">MangaLife</a></span>
</div> -->
</div>
</div>
<div>
<span class="title">Komga</span>
<div>Configured: <span id="komgaConfigured">✅❌</span></div>
<label for="komgaUrl"></label><input placeholder="URL" id="komgaUrl" type="text">
<label for="komgaUsername"></label><input placeholder="Username" id="komgaUsername" type="text">
<label for="komgaPassword"></label><input placeholder="Password" id="komgaPassword" type="password">
</div>
<div>
<span class="title">Kavita</span>
<div>Configured: <span id="kavitaConfigured">✅❌</span></div>
<label for="kavitaUrl"></label><input placeholder="URL" id="kavitaUrl" type="text">
<label for="kavitaUsername"></label><input placeholder="Username" id="kavitaUsername" type="text">
<label for="kavitaPassword"></label><input placeholder="Password" id="kavitaPassword" type="password">
</div>
<div>
<span class="title">Gotify</span>
<div>Configured: <span id="gotifyConfigured">✅❌</span></div>
<label for="gotifyUrl"></label><input placeholder="URL" id="gotifyUrl" type="text">
<label for="gotifyAppToken"></label><input placeholder="App-Token" id="gotifyAppToken" type="text">
</div>
<div>
<span class="title">LunaSea</span>
<div>Configured: <span id="lunaseaConfigured">✅❌</span></div>
<label for="lunaseaWebhook"></label><input placeholder="device/:id or user/:id" id="lunaseaWebhook" type="text">
</div>
<div>
<span class="title">Ntfy</span>
<div>Configured: <span id="ntfyConfigured">✅❌</span></div>
<label for="ntfyEndpoint"></label><input placeholder="URL" id="ntfyEndpoint" type="text">
<label for="ntfyAuth"></label><input placeholder="Auth" id="ntfyAuth" type="text">
</div>
<div>
<span class="title">UserAgent</span><br />
<label for="userAgent"></label><input style="width: 400px" placeholder="UserAgent" id="userAgent" type="text">
</div>
<div>
<input type="checkbox" id="mangaHoverCheckbox" name="css-style" value="style_mangahover.css" onclick="updateCSS()">
<label for="css-style"> Show manga titles and sources on hover</label><br>
</div>
<div>
<input type="submit" value="Update" onclick="UpdateSettings()">
</div>
<div>
<input type="submit" value="Refresh Library Metadata" style="width: fit-content;"onclick="RefreshLibraryMetadata()">
<div class="popup-section">
LIBRARY CONNECTORS
<div class="section-content">
<div class="section-item">
<span class="title"><img src='connector-icons/komga.svg'>Komga<connector-configured id="komgaConfigured"></connector-configured></span>
<label for="komgaUrl"></label><input placeholder="URL" id="komgaUrl" type="text">
<label for="komgaUsername"></label><input placeholder="Username" id="komgaUsername" type="text">
<label for="komgaPassword"></label><input placeholder="Password" id="komgaPassword" type="password">
<div class="section-buttons-container">
<span onclick="TestKomga(komgaUrl.value, utf8_to_b64(`${komgaUsername.value}:${komgaPassword.value}`))" class='section-button' id="test-connector">Test</span>
<span onclick="ClearKomga()" class='section-button' id="reset">Reset</span>
<span onclick="UpdateKomga(komgaUrl.value, utf8_to_b64(`${komgaUsername.value}:${komgaPassword.value}`))" class='section-button'>Apply</span>
</div>
</div>
<div class="section-item">
<span class="title"><img src='connector-icons/kavita.png'>Kavita<connector-configured id="kavitaConfigured"></connector-configured></span>
<label for="kavitaUrl"></label><input placeholder="URL" id="kavitaUrl" type="text">
<label for="kavitaUsername"></label><input placeholder="Username" id="kavitaUsername" type="text">
<label for="kavitaPassword"></label><input placeholder="Password" id="kavitaPassword" type="password">
<div class="section-buttons-container">
<span onclick="TestKavita(kavitaUrl.value, kavitaUsername.value, kavitaPassword.value)" class='section-button' id="test-connector">Test</span>
<span onclick="ClearKavita()" class='section-button' id="reset">Reset</span>
<span onclick="UpdateKavita(kavitaUrl.value, kavitaUsername.value, kavitaPassword.value)" class='section-button'>Apply</span>
</div>
</div>
</div>
</div>
<div class="popup-section">
NOTIFICATION CONNECTORS
<div class="section-content">
<div class="section-item">
<span class="title"><img src='connector-icons/gotify-logo.png'>Gotify<connector-configured id="gotifyConfigured"></connector-configured></span>
<label for="gotifyUrl"></label><input placeholder="URL" id="gotifyUrl" type="text">
<label for="gotifyAppToken"></label><input placeholder="App-Token" id="gotifyAppToken" type="text">
<div class="section-buttons-container">
<span onclick="TestGotify(gotifyUrl.value, gotifyAppToken.value)" class='section-button' id="test-connector">Test</span>
<span onclick="ClearGotify()" class='section-button' id="reset">Reset</span>
<span onclick="UpdateGotify(gotifyUrl.value, gotifyAppToken.value)" class='section-button'>Apply</span>
</div>
</div>
<div class="section-item">
<span class="title"><img src='connector-icons/lunasea.png'>LunaSea<connector-configured id="lunaseaConfigured"></connector-configured></span>
<label for="lunaseaWebhook"></label><input placeholder="device/:id or user/:id" id="lunaseaWebhook" type="text">
<div class="section-buttons-container">
<span onclick="TestLunaSea(lunaseaWebhook.value);" class='section-button' id="test-connector">Test</span>
<span onclick="ClearLunasea()" class='section-button' id="reset">Reset</span>
<span onclick="UpdateLunaSea(lunaseaWebhook.value);" class='section-button'>Apply</span>
</div>
</div>
<div class="section-item">
<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="ntfyAuth"></label><input placeholder="Auth" id="ntfyAuth" type="text">
<div class="section-buttons-container">
<span onclick="TestNtfy(ntfyEndpoint.value, ntfyAuth.value);" class='section-button' id="test-connector">Test</span>
<span onclick="ClearNtfy()" class='section-button' id="reset">Reset</span>
<span onclick="UpdateNtfy(ntfyEndpoint.value, ntfyAuth.value);" class='section-button'>Apply</span>
</div>
</div>
</div>
</div>
</popup-content>
<border-bar>
<div class="button-container">
<border-bar-button class="primary" onclick="UpdateSettings()">Apply Settings</border-bar-button>
</div>
</border-bar>
</popup-window>
</popup>
@ -136,18 +249,39 @@
</publication-details>
</publication-viewer>
</popup>
<popup id="jobStatusView">
<blur-background id="blurBackgroundJobStatus" onclick="jobStatusView.style.display= 'none';"></blur-background>
<blur-background id="blurBackgroundSettingsPopup" onclick="jobStatusView.style.display = 'none';"></blur-background>
<popup-window>
<div>
<div id="jobStatusRunning" style="border-right: 1px solid gray;"></div>
</div>
<div>
<div id="jobStatusWaiting" style="border-left: 1px solid gray;"></div>
</div>
<border-bar>
<popup-title>Jobs</popup-title>
<popup-close onclick="jobStatusView.style.display = 'none'">&times</popup-close>
</border-bar>
<popup-content>
<div class="popup-section">
RUNNING JOBS
<div class="section-content" id="jobStatusRunning">
</div>
</div>
<div class="popup-section">
QUEUED JOBS
<div class="section-content" id="jobStatusWaiting">
</div>
</div>
</popup-content>
<border-bar>
<!-- <div class="button-container">
<border-bar-button class="primary" onclick="UpdateSettings()">Apply Settings</border-bar-button>
</div> -->
</border-bar>
</popup-window>
</popup>
</viewport>
<footer>

View File

@ -5,16 +5,26 @@ let notificationConnectorTypes = [];
let libraryConnectorTypes = [];
let selectedManga;
let selectedJob;
let searchMatch;
let connectorMatch = [];
let connectorNameMatch;
let statusMatch = [];
let statusNameMatch = [];
const searchBox = document.querySelector("#searchbox");
const settingsPopup = document.querySelector("#settingsPopup");
const filterBox = document.querySelector("#filterBox");
const settingsCog = document.querySelector("#settingscog");
const filterFunnel = document.querySelector("#filterFunnel");
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
const mangaViewerPopup = document.querySelector("#publicationViewerPopup");
const mangaViewerWindow = document.querySelector("publication-viewer");
const mangaViewerDescription = document.querySelector("#publicationViewerDescription");
@ -22,31 +32,56 @@ const mangaViewerName = document.querySelector("#publicationViewerName");
const mangaViewerTags = document.querySelector("#publicationViewerTags");
const mangaViewerAuthor = document.querySelector("#publicationViewerAuthor");
const mangaViewCover = document.querySelector("#pubviewcover");
const settingDownloadLocation = document.querySelector("#downloadLocation");
//General Rate Limits
const defaultRL = document.querySelector("#defaultRL");
const coverRL = document.querySelector("#coverRL");
const imageRL = document.querySelector("#imageRL");
const infoRL = document.querySelector("#infoRL");
//MangaDex Rate Limits
const mDexAuthorRL = document.querySelector("#mDexAuthorRL");
const mDexFeedRL = document.querySelector("#mDexFeedRL");
const mDexImageRL = document.querySelector("#mDexImageRL");
//Komga
const settingKomgaUrl = document.querySelector("#komgaUrl");
const settingKomgaUser = document.querySelector("#komgaUsername");
const settingKomgaPass = document.querySelector("#komgaPassword");
//Kavita
const settingKavitaUrl = document.querySelector("#kavitaUrl");
const settingKavitaUser = document.querySelector("#kavitaUsername");
const settingKavitaPass = document.querySelector("#kavitaPassword");
//Gotify
const settingGotifyUrl = document.querySelector("#gotifyUrl");
const settingGotifyAppToken = document.querySelector("#gotifyAppToken");
//Lunasea
const settingLunaseaWebhook = document.querySelector("#lunaseaWebhook");
//Ntfy
const settingNtfyEndpoint = document.querySelector("#ntfyEndpoint");
const settingNtfyAuth = document.querySelector("#ntfyAuth");
//Connector Configured
const settingKomgaConfigured = document.querySelector("#komgaConfigured");
const settingKavitaConfigured = document.querySelector("#kavitaConfigured");
const settingGotifyConfigured = document.querySelector("#gotifyConfigured");
const settingLunaseaConfigured = document.querySelector("#lunaseaConfigured");
const settingNtfyConfigured = document.querySelector("#ntfyConfigured");
const settingUserAgent = document.querySelector("#userAgent");
const settingApiUri = document.querySelector("#settingApiUri");
const settingMangaHoverCheckbox = document.querySelector("#mangaHoverCheckbox");
const settingCSSStyle = document.querySelector('#cssStyle');
const newMangaPopup = document.querySelector("#newMangaPopup");
const newMangaConnector = document.querySelector("#newMangaConnector");
const newMangaTitle = document.querySelector("#newMangaTitle");
const newMangaResult = document.querySelector("#newMangaResult");
const newMangaTranslatedLanguage = document.querySelector("#newMangaTranslatedLanguage");
//Jobs
const jobsRunningTag = document.querySelector("#jobsRunningTag");
const jobsQueuedTag = document.querySelector("#jobsQueuedTag");
const loaderdiv = document.querySelector('#loaderdiv');
@ -59,61 +94,162 @@ function Setup(){
loaderdiv.style.display = 'none';
GetAvailableNotificationConnectors().then((json) => {
//console.log(json);
json.forEach(connector => {
notificationConnectorTypes[connector.Key] = connector.Value;
});
});
GetAvailableLibraryConnectors().then((json) => {
//console.log(json);
json.forEach(connector => {
libraryConnectorTypes[connector.Key] = connector.Value;
});
});
GetAvailableControllers().then((json) => {
//console.log(json);
newMangaConnector.replaceChildren();
json.forEach(connector => {
connectorFilterBox = document.querySelector("#connectorFilterBox");
connectorFilterBox.replaceChildren();
json.forEach(connector => {
//Add the connector to the New Manga dropdown
var option = document.createElement('option');
option.value = connector;
option.innerText = connector;
newMangaConnector.appendChild(option);
//Add the connector to the filter box
connectorFilter = document.createElement('connector-name');
connectorFilter.innerText = connector;
connectorFilter.className = "pill";
connectorFilter.style.backgroundColor = stringToColour(connector);
connectorFilter.addEventListener("click", (event) => {
ToggleFilterConnector(connector, event);
});
connectorFilterBox.appendChild(connectorFilter);
});
});
//Add the publication status options to the filter bar
publicationStatusOptions = ["Ongoing", "Completed", "On Hiatus", "Cancelled", "Upcoming", "Status Unavailable"];
statusFilterBox = document.querySelector("#statusFilterBox");
statusFilterBox.replaceChildren();
publicationStatusOptions.forEach(publicationStatus => {
var releaseStatus = document.createElement('status-filter');
releaseStatus.innerText = publicationStatus;
releaseStatus.setAttribute("release-status", publicationStatus);
releaseStatus.addEventListener("click", (event) => {
ToggleFilterStatus(publicationStatus, event);
});
statusFilterBox.appendChild(releaseStatus);
});
ResetContent();
UpdateJobs();
GetSettings().then((json) => {
//console.log(json);
settingDownloadLocation.innerText = json.downloadLocation;
settingApiUri.placeholder = apiUri;
//console.log(json.styleSheet);
if (json.styleSheet == 'hover') {
settingMangaHoverCheckbox.checked = true;
document.getElementById('pagestyle').setAttribute('href', 'styles/style_mangahover.css');
} else {
settingMangaHoverCheckbox.checked = false;
document.getElementById('pagestyle').setAttribute('href', 'styles/style_default.css');
}
});
GetRateLimits().then((json) => {
defaultRL.placeholder = json.Default + ' Requests/Minute';
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
mDexAuthorRL.placeholder = json.MangaDexAuthor + ' Requests/Minute';
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
});
//If the cssStyle key isn't in the local storage of the browser, then set the css style to the default and load the page
//Otherwise get the style key from storage and set it.
if (!localStorage.getItem('cssStyle')) {
localStorage.setItem('cssStyle', 'card_compact');
document.getElementById('librarystyle').setAttribute('href', 'styles/' + localStorage.getItem('cssStyle') + '.css');
document.getElementById('card_compact').selected = true;
} else {
css_style = localStorage.getItem('cssStyle');
document.getElementById('librarystyle').setAttribute('href', 'styles/' + css_style + '.css');
document.getElementById(css_style).selected = true;
}
setInterval(() => {
UpdateJobs();
}, 1000);
});
//Clear the previous values if any exist.
searchBox.value = "";
connectorMatch.length = 0;
statusMatch.length = 0;
}
Setup();
function updateCSS(){
if (document.getElementById("mangaHoverCheckbox").checked == true){
ChangeStyleSheet('hover')
document.getElementById('pagestyle').setAttribute('href', 'styles/style_mangahover.css');
//console.log('Changing theme to mangahover')
function ToggleFilterConnector(connector, event) {
//console.log("Initial Array:");
//console.log(connectorMatch);
if (connectorMatch.includes(connector)) {
idx = connectorMatch.indexOf(connector);
connectorMatch.splice(idx, 1);
event.target.style.outline = 'none';
event.target.style.outlineOffset = "0px";
} else {
ChangeStyleSheet('default');
document.getElementById('pagestyle').setAttribute('href', 'styles/style_default.css');
//console.log('Changing theme to default')
connectorMatch.push(connector);
event.target.style.outline = '4px solid var(--secondary-color)';
event.target.style.outlineOffset = '3px';
}
//console.log("Final Array");
//console.log(connectorMatch);
FilterResults();
}
function ToggleFilterStatus(status, event) {
//console.log("Initial Array:");
//console.log(statusMatch);
if (statusMatch.includes(status)) {
idx = statusMatch.indexOf(status);
statusMatch.splice(idx, 1);
event.target.style.outline = 'none';
event.target.style.outlineOffset = "0px";
} else {
statusMatch.push(status);
event.target.style.outline = '4px solid var(--secondary-color)';
event.target.style.outlineOffset = '3px';
}
//console.log("Final Array");
//console.log(statusMatch);
FilterResults();
}
function ClearFilter() {
searchBox.value = "";
statusMatch.length = 0;
connectorMatch.length = 0;
FilterResults();
//Get rid of the outlines
connectorFilterBox = document.querySelector("#connectorFilterBox");
connectorFilterBox.childNodes.forEach(connector => {
if (connector.nodeName.toLowerCase() == 'connector-name') {
connector.style.outline = 'none';
connector.style.outlineOffset = "0px";
}
});
statusFilterBox = document.querySelector("#statusFilterBox");
statusFilterBox.childNodes.forEach(publicationStatus => {
if (publicationStatus.nodeName.toLowerCase() == 'status-filter') {
publicationStatus.style.outline = 'none';
publicationStatus.style.outlineOffset = "0px";
}
});
}
settingCSSStyle.addEventListener("change", (event) => {
localStorage.setItem('cssStyle', settingCSSStyle.value);
document.getElementById('librarystyle').setAttribute('href', 'styles/' + localStorage.getItem('cssStyle') + '.css');
});
function ResetContent(){
//Delete everything
tasksContent.replaceChildren();
@ -147,7 +283,11 @@ function ShowNewMangaSearch(){
newMangaResult.replaceChildren();
}
newMangaTitle.addEventListener("keypress", (event) => { if(event.key === "Enter") GetNewMangaItems();})
newMangaTitle.addEventListener("keypress", (event) => { if(event.key === "Enter") GetNewMangaItems();});
function GetNewMangaItems(){
if(newMangaTitle.value.length < 4)
return;
@ -231,7 +371,6 @@ createMonitorJobButton.addEventListener("click", () => {
CreateMonitorJob(newMangaConnector.value, selectedManga.internalId, newMangaTranslatedLanguage.value);
UpdateJobs();
mangaViewerPopup.style.display = "none";
ResetContent();
});
startJobButton.addEventListener("click", () => {
StartJob(selectedJob.id);
@ -245,7 +384,6 @@ deleteJobButton.addEventListener("click", () => {
RemoveJob(selectedJob.id);
UpdateJobs();
mangaViewerPopup.style.display = "none";
ResetContent();
});
function ShowMangaWindow(job, manga, event, add){
@ -297,25 +435,72 @@ function HidePublicationPopup(){
searchBox.addEventListener("keyup", () => FilterResults());
//Filter shown jobs
function FilterResults(){
if(searchBox.value.length > 0){
tasksContent.childNodes.forEach(publication => {
publication.childNodes.forEach(item => {
if(item.nodeName.toLowerCase() == "publication-information"){
item.childNodes.forEach(information => {
if(information.nodeName.toLowerCase() == "publication-name"){
if(!information.textContent.toLowerCase().includes(searchBox.value.toLowerCase())){
publication.style.display = "none";
}else{
publication.style.display = "initial";
}
}
});
}
});
});
}else{
tasksContent.childNodes.forEach(publication => publication.style.display = "initial");
//For each publication
tasksContent.childNodes.forEach(publication => {
//If the search box isn't empty check that the title contains the searchbox content. If it does then
//'searchMatch' is true and the manga is shown. If the search box is empty, then consider this field
//to be true anyways.
if (searchBox.value.length > 0) {
publication.childNodes.forEach(item => {
if (item.nodeName.toLowerCase() == "publication-information"){
item.childNodes.forEach(information => {
if (information.nodeName.toLowerCase() == "publication-name") {
if (information.textContent.toLowerCase().includes(searchBox.value.toLowerCase())){
searchMatch = 1;
} else {
searchMatch = 0;
}
}
});
}
});
} else {
searchMatch = 1;
}
//If the array connectorMatch isn't empty then check that the connector matches one of the ones
//in the array
if (connectorMatch.length > 0) {
publication.childNodes.forEach(item => {
if (item.nodeName.toLowerCase() == "publication-information"){
item.childNodes.forEach(information => {
if (information.nodeName.toLowerCase() == "connector-name") {
if (connectorMatch.includes(information.textContent)){
connectorNameMatch = 1;
} else {
connectorNameMatch = 0;
}
}
});
}
});
} else {
connectorNameMatch = 1;
}
//If the array statusMatch isn't empty then check that the status matches one of the ones
//in the array
if (statusMatch.length > 0) {
publication.childNodes.forEach(item => {
if (item.nodeName.toLowerCase() == "publication-status"){
if (statusMatch.includes(item.getAttribute('release-status'))) {
statusNameMatch = 1;
} else {
statusNameMatch = 0;
}
}
});
} else {
statusNameMatch = 1;
}
//If all of the filtering conditions are met then show the manga, otherwise hide it.
if (searchMatch && connectorNameMatch && statusNameMatch) {
publication.style.display = 'initial';
} else {
publication.style.display = 'none';
}
});
}
settingsCog.addEventListener("click", () => {
@ -323,7 +508,11 @@ settingsCog.addEventListener("click", () => {
settingsPopup.style.display = "flex";
});
settingKomgaUrl.addEventListener("keypress", (event) => { { if(event.key === "Enter") UpdateSettings(); } });
filterFunnel.addEventListener("click", () => {
filterBox.classList.toggle("animate");
});
settingKomgaUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
settingKomgaUser.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
settingKomgaPass.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
settingKavitaUrl.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
@ -337,12 +526,21 @@ settingNtfyAuth.addEventListener("keypress", (event) => { if(event.key === "Ente
settingUserAgent.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
settingApiUri.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings(); });
defaultRL.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();});
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();});
mDexImageRL.addEventListener("keypress", (event) => { if(event.key === "Enter") UpdateSettings();});
function OpenSettings(){
settingGotifyConfigured.innerText = "❌";
settingLunaseaConfigured.innerText = "❌";
settingNtfyConfigured.innerText = "❌";
settingKavitaConfigured.innerText = "❌";
settingKomgaConfigured.innerText = "❌";
settingGotifyConfigured.setAttribute("configuration", "Not Configured");
settingLunaseaConfigured.setAttribute("configuration", "Not Configured");
settingNtfyConfigured.setAttribute("configuration", "Not Configured");
settingKavitaConfigured.setAttribute("configuration", "Not Configured");
settingKomgaConfigured.setAttribute("configuration", "Not Configured");
settingKomgaUrl.value = "";
settingKomgaUser.value = "";
settingKomgaPass.value = "";
@ -356,37 +554,44 @@ function OpenSettings(){
settingNtfyEndpoint.value = "";
settingUserAgent.value = "";
settingApiUri.value = "";
settingMangaHoverCheckbox.checked = false;
defaultRL.value = "";
coverRL.value = "";
imageRL.value = "";
infoRL.value = "";
mDexAuthorRL.value = "";
mDexFeedRL.value = "";
mDexImageRL.value = "";
GetSettings().then((json) => {
//console.log(json);
settingDownloadLocation.innerText = json.downloadLocation;
settingApiUri.placeholder = apiUri;
settingUserAgent.placeholder = json.userAgent;
settingApiUri.value = apiUri;
settingUserAgent.value = json.userAgent;
//console.log(json.styleSheet);
if (json.styleSheet == 'hover') {
settingMangaHoverCheckbox.checked = true;
document.getElementById('pagestyle').setAttribute('href', 'styles/style_mangahover.css');
} else {
settingMangaHoverCheckbox.checked = false;
document.getElementById('pagestyle').setAttribute('href', 'styles/style_default.css');
}
});
GetRateLimits().then((json) => {
defaultRL.placeholder = json.Default + ' Requests/Minute';
coverRL.placeholder = json.MangaCover + ' Requests/Minute';
imageRL.placeholder = json.MangaImage + ' Requests/Minute';
infoRL.placeholder = json.MangaInfo + ' Requests/Minute';
mDexAuthorRL.placeholder = json.MangaDexAuthor + ' Requests/Minute';
mDexFeedRL.placeholder = json.MangaDexFeed + ' Requests/Minute';
mDexImageRL.placeholder = json.MangaDexImage + ' Requests/Minute';
});
GetLibraryConnectors().then((json) => {
//console.log(json);
json.forEach(connector => {
switch(libraryConnectorTypes[connector.libraryType]){
case "Kavita":
settingKavitaConfigured.innerText = "✅";
settingKavitaUrl.placeholder = connector.baseUrl;
settingKavitaUser.placeholder = "***";
settingKavitaPass.placeholder = "***";
settingKavitaConfigured.setAttribute("configuration", "Active");
settingKavitaUrl.value = connector.baseUrl;
settingKavitaUser.value = "***";
settingKavitaPass.value = "***";
break;
case "Komga":
settingKomgaConfigured.innerText = "✅";
settingKomgaUrl.placeholder = connector.baseUrl;
settingKomgaUser.placeholder = "***";
settingKomgaPass.placeholder = "***";
settingKomgaConfigured.setAttribute("configuration", "Active");
settingKomgaUrl.value = connector.baseUrl;
settingKomgaUser.value = "***";
settingKomgaPass.value = "***";
break;
default:
console.log("Unknown type");
@ -396,22 +601,21 @@ function OpenSettings(){
});
});
GetNotificationConnectors().then((json) => {
//console.log(json);
json.forEach(connector => {
switch(notificationConnectorTypes[connector.notificationConnectorType]){
case "Gotify":
settingGotifyUrl.placeholder = connector.endpoint;
settingGotifyAppToken.placeholder = "***";
settingGotifyConfigured.innerText = "✅";
settingGotifyUrl.value = connector.endpoint;
settingGotifyAppToken.value = "***";
settingGotifyConfigured.setAttribute("configuration", "Active");
break;
case "LunaSea":
settingLunaseaConfigured.innerText = "✅";
settingLunaseaWebhook.placeholder = connector.id;
settingLunaseaConfigured.setAttribute("configuration", "Active");
settingLunaseaWebhook.value = connector.id;
break;
case "Ntfy":
settingNtfyConfigured.innerText = "✅";
settingNtfyEndpoint.placeholder = connector.endpoint;
settingNtfyAuth.placeholder = "***";
settingNtfyConfigured.setAttribute("configuration", "Active");
settingNtfyEndpoint.value = connector.endpoint;
settingNtfyAuth.value = "***";
break;
default:
console.log("Unknown type");
@ -422,6 +626,43 @@ function OpenSettings(){
});
}
//Functions for clearing/resetting connectors in the settings pop-up
function ClearKomga(){
settingKomgaUrl.value = "";
settingKomgaUser.value = "";
settingKomgaPass.value = "";
settingKomgaConfigured.setAttribute("configuration", "Not Configured");
ResetKomga();
}
function ClearKavita(){
settingKavitaUrl.value = "";
settingKavitaUser.value = "";
settingKavitaPass.value = "";
settingKavitaConfigured.setAttribute("configuration", "Not Configured");
ResetKavita();
}
function ClearGotify(){
settingGotifyUrl.value = "";
settingGotifyAppToken.value = ""
settingGotifyConfigured.setAttribute("configuration", "Not Configured");
ResetGotify();
}
function ClearLunasea(){
settingLunaseaWebhook.value = "";
settingLunaseaConfigured.setAttribute("configuration", "Not Configured");
ResetLunaSea();
}
function ClearNtfy(){
settingNtfyEndpoint.value = "";
settingNtfyAuth.value = "";
settingNtfyConfigured.setAttribute("configuration", "Not Configured");
ResetNtfy();
}
function UpdateSettings(){
if(settingApiUri.value != ""){
apiUri = settingApiUri.value;
@ -458,6 +699,34 @@ function UpdateSettings(){
if(settingUserAgent.value != ""){
UpdateUserAgent(settingUserAgent.value);
}
if (defaultRL.value != "") {
UpdateRateLimit(0, defaultRL.value);
}
if (coverRL.value != "") {
UpdateRateLimit(3, coverRL.value);
}
if (imageRL.value != "") {
UpdateRateLimit(2, imageRL.value);
}
if (infoRL.value != "") {
UpdateRateLimit(6, infoRL.value);
}
if (mDexAuthorRL.value != "") {
UpdateRateLimit(5, mDexAuthorRL.value);
}
if (mDexFeedRL.value != "") {
UpdateRateLimit(1, mDexFeedRL.value);
}
if (mDexImageRL.value != "") {
UpdateRateLimit(5, mDexImageRL.value);
}
setTimeout(() => {
OpenSettings();
@ -474,14 +743,6 @@ function UpdateJobs(){
GetMonitorJobs().then((json) => {
if(monitoringJobsCount != json.length){
ResetContent();
//console.log(json);
json.forEach(job => {
var mangaView = CreateManga(job.manga, job.mangaConnector.name);
mangaView.addEventListener("click", (event) => {
ShowMangaWindow(job, job.manga, event, false);
});
tasksContent.appendChild(mangaView);
});
monitoringJobsCount = json.length;
}
});
@ -541,39 +802,44 @@ function createJob(jobjson){
var wrapper = document.createElement("div");
wrapper.className = "jobWrapper";
wrapper.className = "section-item";
wrapper.id = GetValidSelector(jobjson.id);
var image = document.createElement("img");
image.className = "jobImage";
image.src = GetCoverUrl(manga.internalId);
wrapper.appendChild(image);
var details = document.createElement("div");
details.className = 'jobDetails';
var title = document.createElement("span");
title.className = "jobTitle";
if(jobjson.chapter != null)
title.innerText = `${manga.sortName} - ${jobjson.chapter.fileName}`;
else if(jobjson.manga != null)
title.innerText = manga.sortName;
wrapper.appendChild(title);
details.appendChild(title);
var progressBar = document.createElement("progress");
progressBar.className = "jobProgressBar";
progressBar.id = `jobProgressBar${GetValidSelector(jobjson.id)}`;
wrapper.appendChild(progressBar);
details.appendChild(progressBar);
var progressSpan = document.createElement("span");
progressSpan.className = "jobProgressSpan";
progressSpan.id = `jobProgressSpan${GetValidSelector(jobjson.id)}`;
progressSpan.innerText = "0% 00:00:00";
wrapper.appendChild(progressSpan);
progressSpan.innerText = "Pending...";
details.appendChild(progressSpan);
var cancelSpan = document.createElement("span");
cancelSpan.className = "jobCancel";
cancelSpan.innerText = "Cancel";
cancelSpan.addEventListener("click", () => CancelJob(jobjson.id));
wrapper.appendChild(cancelSpan);
details.appendChild(cancelSpan);
wrapper.appendChild(details);
return wrapper;
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg fill="#000000" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="800px" height="800px" viewBox="0 0 971.986 971.986"
xml:space="preserve">
<g>
<path d="M370.216,459.3c10.2,11.1,15.8,25.6,15.8,40.6v442c0,26.601,32.1,40.101,51.1,21.4l123.3-141.3
c16.5-19.8,25.6-29.601,25.6-49.2V500c0-15,5.7-29.5,15.8-40.601L955.615,75.5c26.5-28.8,6.101-75.5-33.1-75.5h-873
c-39.2,0-59.7,46.6-33.1,75.5L370.216,459.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 714 B

View File

@ -1,9 +1,14 @@
:root{
--background-color: #030304;
--second-background-color: #fff;
--second-background-color: white;
--primary-color: #f5a9b8;
--secondary-color: #5bcefa;
--secondary-color: #5bcefa;
--blur-background: rgba(245, 169, 184, 0.58);
--accent-color: #fff;
/* --primary-color: green;
--secondary-color: gold;
--blur-background: rgba(86, 131, 36, 0.8);
--accent-color: olive; */
--topbar-height: 60px;
box-sizing: border-box;
}
@ -64,7 +69,6 @@ titlebox span{
titlebox img {
height: 100%;
margin-right: 10px;
cursor: grab;
}
@ -72,22 +76,156 @@ spacer{
flex-grow: 1;
}
searchdiv{
filter-box {
display: none;
align-self: center;
flex-direction: column;
position: relative;
margin: 10px;
background-color: var(--second-background-color);
border-style: solid;
border-color: var(--primary-color);
border-width: 2px;
border-radius: 15px;
min-width: 300px;
width: 50%;
overflow: hidden;
max-height: 50%;
height: 600px;
}
filter-box.animate {
display: flex;
}
filter-box border-bar popup-title{
font-size: 12pt;
}
filter-box border-bar popup-close {
height: 20px;
width: 20px;
font-size: 12pt;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
border-bar-button.clearFilter{
font-weight: bold;
margin: 0px 10px 10px 10px;
border-color: lightgray;
color: gray;
align-content: center;
justify-content: center;
}
border-bar-button.clearFilter:hover {
background-color: red;
border-color: var(--second-background-color);
color: var(--second-background-color);
}
status-filter {
display: block;
margin: 0 10px 0 0;
margin: 10px;
/*Text Properties*/
font-size:10pt;
font-weight:bold;
color:white;
text-align: center;
/*Size*/
padding: 3px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
cursor: pointer;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
status-filter[release-status="Ongoing"]{
background-color: limegreen;
}
status-filter[release-status="Completed"]{
background-color: blueviolet;
}
status-filter[release-status="On Hiatus"]{
background-color: darkorange;
}
status-filter[release-status="Cancelled"]{
background-color: firebrick;
}
status-filter[release-status="Upcoming"]{
background-color: aqua;
}
status-filter[release-status="Status Unavailable"]{
background-color: gray;
}
searchdiv{
display: flex;
width: 100%;
}
#searchbox {
padding: 3px 10px;
border: 0;
border-radius: 4px;
font-size: 14pt;
width: 250px;
display: flex;
padding: 3px 5px;
margin: 5px;
border-style: solid;
border-width: 2px;
border-radius: 10px;
font-size: 12pt;
outline: none;
border-color: lightgray;
flex-grow: 1;
flex-shrink: 1;
}
#searchbox:focus {
border-color: var(--secondary-color);
}
.pill {
flex-grow: 0;
height: 14pt;
font-size: 12pt;
border-radius: 9pt;
background-color: var(--primary-color);
padding: 2pt 17px;
color: black;
}
#connectorFilterBox .pill {
margin: 10px;
cursor: pointer;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
#settingscog {
cursor: pointer;
margin: 0px 30px;
margin-left: 15px;
height: 50%;
filter: invert(100%) sepia(0%) saturate(7465%) hue-rotate(115deg) brightness(116%) contrast(101%);
}
#filterFunnel {
cursor: pointer;
margin: 0px 15px;
height: 50%;
filter: invert(100%) sepia(0%) saturate(7465%) hue-rotate(115deg) brightness(116%) contrast(101%);
}
@ -153,192 +291,6 @@ content {
z-index: 300;
}
#settingsPopup popup-content{
flex-direction: column;
align-items: start;
margin: 15px 10px;
}
#settingsPopup popup-content > * {
margin: 5px 10px;
}
#settingsPopup popup-content .title {
font-weight: bolder;
}
#addPublication {
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 20px;
position: relative;
}
#addPublication p{
width: 100%;
text-align: center;
font-size: 150pt;
vertical-align: middle;
line-height: 300px;
margin: 0;
color: var(--accent-color);
}
.pill {
flex-grow: 0;
height: 14pt;
font-size: 12pt;
border-radius: 9pt;
background-color: var(--primary-color);
padding: 2pt 17px;
color: black;
}
publication{
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 19px;
position: relative;
flex-shrink: 0;
}
publication:hover {
background-color: black;
}
publication:hover::after{
background: linear-gradient(rgba(0,0,0,0.8), rgba(0, 0, 0, 0.7),rgba(0, 0, 0, 0.2));
}
publication:hover > publication-information {
display: flex;
opacity:1;
}
publication::after{
content: '';
position: absolute;
left: 0; top: 0;
border-radius: 5px;
width: 100%; height: 100%;
}
publication-information {
display: none;
flex-direction: column;
justify-content: start;
}
publication-information * {
z-index: 1;
color: var(--accent-color);
}
connector-name{
width: fit-content;
margin: 10px 0;
}
publication-name{
width: fit-content;
font-size: 16pt;
font-weight: bold;
}
publication-status {
display:block;
height: 10px;
width: 10px;
border-radius: 50%;
margin: 5px;
position: absolute;
top: 5px;
right: 5px;
z-index: 2;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 10px, rgb(51, 51, 51) 0px 0px 10px 3px;
}
publication-status::after {
content: attr(release-status);
position: absolute;
top: 0;
right: 0;
visibility: hidden;
/*Text Properties*/
font-size:10pt;
font-weight:bold;
color:white;
text-align: center;
/*Size*/
padding: 3px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
}
publication-status:hover::after{
visibility:visible;
}
publication-status[release-status="Ongoing"]{
background-color: limegreen;
}
publication-status[release-status="Completed"]{
background-color: blueviolet;
}
publication-status[release-status="On Hiatus"]{
background-color: darkorange;
}
publication-status[release-status="Cancelled"]{
background-color: firebrick;
}
publication-status[release-status="Upcoming"]{
background-color: aqua;
}
publication-status[release-status="Status Unavailable"]{
background-color: gray;
}
publication-details {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-details * {
z-index: 1;
color: var(--accent-color);
}
publication img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
border-radius: 5px;
}
popup{
display: none;
width: 100%;
@ -350,49 +302,353 @@ popup{
flex-direction: column;
}
border-bar {
display: flex;
flex-direction: row;
background-color: var(--primary-color);
color: var(--accent-color);
font-weight: bolder;
padding: 7px 5px;
margin:0;
align-items: center;
position: relative;
width: 100%;
}
popup-title {
font-size: 14pt;
display: flex;
margin-top: 3px;
margin-left: 5px;
color: var(--second-background-color);
}
popup-close {
border: none;
background-color: inherit;
color: var(--second-background-color);;
font-weight: inherit;
font-size: 27px;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
display: flex;
cursor: pointer;
margin-left: auto;
margin-right: 15px;
height: 32px;
width: 32px;
border-radius: 16px;
align-content: center;
justify-content: center;
}
popup-close:hover {
background-color: var(--secondary-color);
}
border-bar > .button-container {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
margin-right: 0;
margin-left: auto;
}
border-bar-button {
border-style: solid;
border-width: 2px;
background-color: inherit;
color: var(--second-background-color);
font-weight: inherit;
font-size: inherit;
font-family: inherit;
display: flex;
cursor: pointer;
margin: 0px 5px;
padding: 5px 20px;
border-radius: 20px;
height: 20px;
align-items: center;
border-color: var(--accent-color);
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
border-bar-button:hover {
border-color: var(--secondary-color);
}
border-bar-button.primary {
background-color: var(--secondary-color);
color: var(--accent-color);
border-color: var(--primary-color);
margin-right: 10px;
}
border-bar-button.primary:hover {
border-color: var(--accent-color);
}
border-bar-button.section {
font-weight: bold;
color: darkgray;
border-color: darkgray;
text-align: center;
padding: 5px;
flex-grow: 1;
justify-content: center;
}
border-bar-button.section:hover {
color: var(--secondary-color);
border-color: var(--secondary-color);
}
popup popup-window {
position: absolute;
z-index: 3;
left: 25%;
top: 100px;
width: 50%;
left: 10%;
top: 10%;
height: 80%;
width: 80%;
display: flex;
flex-direction: column;
background-color: var(--second-background-color);
border-radius: 3px;
border-radius: 15px;
overflow: hidden;
}
popup popup-window popup-title {
popup#jobStatusView popup-window {
left: 20%;
top: 20%;
height: 60%;
width: 60%;
}
popup-content{
display: flex;
flex-direction: column;
align-items: left;
height: calc(100% - 60px);
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: var(--secondary-color) var(--second-background-color);
}
popup-content > .popup-section {
margin: 5px;
margin-bottom: 10px;
font-size: 10pt;
font-weight: 100;
display: block;
border-top-style: solid;
border-top-width: 1px;
border-top-color: lightgray;
width: calc(100%-10px);
padding: 10px;
}
.section-content {
display: flex;
flex-direction: row;
width: 100%;
flex-wrap: wrap;
}
.section-item {
display: flex;
flex-direction: column;
width: 22%;
min-width: 300px;
height: auto;
border-radius: 10px;
border-style: solid;
border-width: 1px;
border-color: lightgray;
margin: 7px;
padding: 5px;
}
.section-item.dyn-height {
height: fit-content;
}
.section-item > .title {
font-weight: bold;
vertical-align: bottom;
line-height: 32px;
font-size: 12pt;
width: 100%;
}
a:link {
color: inherit;
text-decoration: none;
}
a:visited {
color: inherit;
text-decoration: none;
}
a:hover {
color: inherit;
text-decoration: underline solid var(--secondary-color) 3px;
}
a:active {
color: inherit;
text-decoration: none;
}
.section-item > .title > img {
width: auto;
height: 32px;
margin: 5px;
vertical-align: middle;
border-radius: 5px;
}
.section-item > .title > connector-configured {
display:block;
height: 10px;
width: 10px;
border-radius: 50%;
margin: 5px;
float: right;
top: 5px;
right: 5px;
}
.section-item > .title > connector-configured::after {
display: block;
content: attr(configuration);
float: right;
width: max-content;
width: -webkit-max-content;
width: -mox-max-content;
width: intrinsic;
visibility: hidden;
/*Text Properties*/
font-size:8pt;
font-weight:bold;
color:white;
text-align: right;
/*Size*/
padding: 0px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
}
.section-item > .title > connector-configured:hover::after{
visibility:visible;
}
.section-item > .title > connector-configured[configuration="Active"] {
background-color: limegreen;
}
.section-item > .title > connector-configured[configuration="Not Configured"] {
background-color: gray;
}
.section-item > input {
margin: 2px;
padding: 5px;
height: 20px;
border-radius: 10px;
border-style: solid;
outline: none;
}
.section-item > input:focus {
border-color: var(--secondary-color);
}
.section-item > row {
width: calc(100%-20px);
display: flex;
flex-direction: row;
align-items: center;
margin-left: 5px;
margin-bottom: 5px;
}
.section-item > row > input {
margin-left: auto;
margin-right: 2px;
padding: 5px;
height: 20px;
border-radius: 10px;
border-style: solid;
outline: none;
flex-grow: 0;
text-align: end;
float: right;
width: 200px;
}
.section-item > row > input:focus {
border-color: var(--secondary-color);
}
.section-item > row > select {
margin-left: auto;
margin-right: 2px;
padding: 2px;
height: 30px;
font-size: 14pt;
font-weight: bolder;
padding: 5px 10px;
margin: 0;
border-radius: 10px;
border-style: solid;
outline: none;
flex-grow: 0;
text-align: end;
float: right;
width: 200px;
}
.section-item > row > select:focus {
border-color: var(--secondary-color);
}
.section-buttons-container {
display: flex;
flex-direction: row;
align-items: center;
background-color: var(--primary-color);
color: var(--accent-color)
position: relative;
margin-left: auto;
margin-top: auto;
margin-bottom: 0;
margin-right: 0;
}
popup popup-window popup-content{
margin: 15px 10px;
display: flex;
align-items: center;
justify-content: space-evenly;
.section-buttons-container > .section-button {
font-size: 12px;
padding: 3px 10px;
margin: 3px;
border-radius: 5px;
border-style: solid;
border-width: 1px;
border-color: lightgray;
font-weight: bold;
color: gray;
cursor: pointer;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}
popup popup-window popup-content div > * {
margin: 2px 3px 0 0;
.section-button#reset:hover {
color: red;
border-color: red;
}
popup popup-window popup-content input, select {
padding: 3px 4px;
width: 130px;
border: 1px solid lightgrey;
background-color: var(--accent-color);
border-radius: 3px;
.section-buttons-container > .section-button:hover {
border-color: var(--secondary-color);
color: var(--secondary-color);
}
#newMangaPopup > div {
@ -453,7 +709,7 @@ blur-background {
height: 100%;
position: absolute;
left: 0;
background: rgba(245, 169, 184, 0.58);
background: var(--blur-background);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(4.5px);
-webkit-backdrop-filter: blur(4.5px);
@ -645,82 +901,59 @@ footer-tag-popup::before{
100% { transform: rotate(360deg); }
}
#jobStatusView {
z-index: 50;
#jobStatusRunning > .section-item {
flex-direction: row;
height: 150px;
padding: 0;
overflow: hidden;
}
#jobStatusView > popup-window {
top: 80px;
width: 50%;
max-height: calc(100% - 140px);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background-color: transparent;
#jobStatusWaiting > .section-item {
flex-direction: row;
height: 150px;
padding: 0;
overflow: hidden;
}
#jobStatusView > popup-window > div {
overflow-y: scroll;
overflow-x: hidden;
width: 50%;
margin: 0;
max-height: 100%;
.section-item > .jobImage {
height: 100%;
width: auto;
left: 0;
top: 0;
border-radius: 10px;
}
#jobStatusView > popup-window > div > div {
overflow-x: hidden;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: 100%;
margin: 0;
.jobDetails {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.jobWrapper {
width: 90%;
margin: 2px 5%;
height: 100px;
position: relative;
flex-shrink: 0;
background-color: rgba(187,187,187,0.4);
border-radius: 3px;
.section-item > .jobDetails > .jobTitle {
margin: 5px;
font-size: 11pt;
font-weight: bold;
text-wrap: wrap;
}
.jobWrapper > .jobImage {
height: 90%;
width: 20%;
left: 5px;
object-fit: contain;
position: absolute;
top: 5%;
}
.jobWrapper > .jobTitle {
position: absolute;
left: calc(20% + 10px);
top: 5px;
}
.jobWrapper > .jobProgressBar {
position: absolute;
left: calc(20% + 10px);
bottom: calc(12pt + 10px);
width: calc(80% - 20px);
.section-item > .jobDetails > .jobProgressBar {
margin: 5px;
height: 10px;
border-radius: 7px;
}
.jobWrapper > .jobProgressSpan {
position: absolute;
right: 10px;
bottom: calc(12pt + 20px);
width: 60%;
text-align: right;
.section-item > .jobDetails > .jobProgressSpan {
margin: 5px;
margin-left: auto;
margin-right: 5px;
}
.jobWrapper > .jobCancel {
position: absolute;
right: 10px;
bottom: 5px;
.section-item > .jobDetails > .jobCancel {
margin-top: auto;
margin-bottom: 5px;
margin-left: auto;
margin-right: 5px;
font-size: 12pt;
color: var(--secondary-color);
cursor: pointer;

View File

@ -0,0 +1,159 @@
#addPublication {
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 20px;
position: relative;
}
#addPublication p{
width: 100%;
text-align: center;
font-size: 150pt;
vertical-align: middle;
line-height: 300px;
margin: 0;
color: var(--accent-color);
}
.pill {
flex-grow: 0;
height: 14pt;
font-size: 12pt;
border-radius: 9pt;
background-color: var(--primary-color);
padding: 2pt 17px;
color: black;
}
publication{
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 19px;
position: relative;
flex-shrink: 0;
}
publication::after{
content: '';
position: absolute;
left: 0; top: 0;
border-radius: 5px;
width: 100%; height: 100%;
background: linear-gradient(rgba(0,0,0,0.8), rgba(0, 0, 0, 0.7),rgba(0, 0, 0, 0.2));
}
publication-information {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-details {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-information * {
z-index: 1;
color: var(--accent-color);
}
publication-details * {
z-index: 1;
color: var(--accent-color);
}
connector-name{
width: fit-content;
margin: 10px 0;
}
publication-name{
width: fit-content;
font-size: 16pt;
font-weight: bold;
color: white;
}
publication-status {
display:block;
height: 10px;
width: 10px;
border-radius: 50%;
margin: 5px;
position: absolute;
top: 5px;
right: 5px;
z-index: 2;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 10px, rgb(51, 51, 51) 0px 0px 10px 3px;
}
publication-status::after {
content: attr(release-status);
position: absolute;
top: 0;
right: 0;
visibility: hidden;
/*Text Properties*/
font-size:10pt;
font-weight:bold;
color:white;
text-align: center;
/*Size*/
padding: 3px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
}
publication-status:hover::after{
visibility:visible;
}
publication-status[release-status="Ongoing"]{
background-color: limegreen;
}
publication-status[release-status="Completed"]{
background-color: blueviolet;
}
publication-status[release-status="On Hiatus"]{
background-color: darkorange;
}
publication-status[release-status="Cancelled"]{
background-color: firebrick;
}
publication-status[release-status="Upcoming"]{
background-color: aqua;
}
publication-status[release-status="Status Unavailable"]{
background-color: gray;
}
publication img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
border-radius: 5px;
}

View File

@ -0,0 +1,172 @@
#addPublication {
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 20px;
position: relative;
}
#addPublication p{
width: 100%;
text-align: center;
font-size: 150pt;
vertical-align: middle;
line-height: 300px;
margin: 0;
color: var(--accent-color);
}
.pill {
flex-grow: 0;
height: 14pt;
font-size: 12pt;
border-radius: 9pt;
background-color: var(--primary-color);
padding: 2pt 17px;
color: black;
}
publication{
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 19px;
position: relative;
flex-shrink: 0;
}
publication:hover {
background-color: black;
}
publication:hover::after{
background: linear-gradient(rgba(0,0,0,0.8), rgba(0, 0, 0, 0.7),rgba(0, 0, 0, 0.2));
}
publication:hover > publication-information {
display: flex;
opacity:1;
}
publication::after{
content: '';
position: absolute;
left: 0; top: 0;
border-radius: 5px;
width: 100%; height: 100%;
background: none;
}
publication-information {
display: none;
flex-direction: column;
justify-content: start;
}
publication-information * {
z-index: 1;
color: white;
}
connector-name{
width: fit-content;
margin: 10px 0;
}
publication-name{
width: fit-content;
font-size: 16pt;
font-weight: bold;
}
publication-status {
display:block;
height: 10px;
width: 10px;
border-radius: 50%;
margin: 5px;
position: absolute;
top: 5px;
right: 5px;
z-index: 2;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 10px, rgb(51, 51, 51) 0px 0px 10px 3px;
}
publication-status::after {
content: attr(release-status);
position: absolute;
top: 0;
right: 0;
visibility: hidden;
/*Text Properties*/
font-size:10pt;
font-weight:bold;
color:white;
text-align: center;
/*Size*/
padding: 3px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
}
publication-status:hover::after{
visibility:visible;
}
publication-status[release-status="Ongoing"]{
background-color: limegreen;
}
publication-status[release-status="Completed"]{
background-color: blueviolet;
}
publication-status[release-status="On Hiatus"]{
background-color: darkorange;
}
publication-status[release-status="Cancelled"]{
background-color: firebrick;
}
publication-status[release-status="Upcoming"]{
background-color: aqua;
}
publication-status[release-status="Status Unavailable"]{
background-color: gray;
}
publication-details {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-details * {
z-index: 1;
color: var(--accent-color);
}
publication img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
border-radius: 5px;
}

View File

@ -1,714 +0,0 @@
:root{
--background-color: #030304;
--second-background-color: #fff;
--primary-color: #f5a9b8;
--secondary-color: #5bcefa;
--accent-color: #fff;
--topbar-height: 60px;
box-sizing: border-box;
}
body{
padding: 0;
margin: 0;
height: 100vh;
background-color: var(--background-color);
font-family: "Inter", sans-serif;
overflow-x: hidden;
}
wrapper {
display: flex;
flex-flow: column;
flex-wrap: nowrap;
height: 100vh;
}
background-placeholder{
background-color: var(--second-background-color);
opacity: 1;
position: absolute;
width: 100%;
height: 100%;
border-radius: 0 0 5px 0;
z-index: -1;
}
topbar {
display: flex;
align-items: center;
height: var(--topbar-height);
background-color: var(--secondary-color);
z-index: 100;
box-shadow: 0 0 20px black;
}
titlebox {
position: relative;
display: flex;
margin: 0 0 0 40px;
height: 100%;
align-items:center;
justify-content:center;
}
titlebox span{
cursor: default;
font-size: 24pt;
font-weight: bold;
background: linear-gradient(150deg, var(--primary-color), var(--accent-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-left: 20px;
}
titlebox img {
height: 100%;
margin-right: 10px;
cursor: grab;
}
spacer{
flex-grow: 1;
}
searchdiv{
display: block;
margin: 0 10px 0 0;
}
#searchbox {
padding: 3px 10px;
border: 0;
border-radius: 4px;
font-size: 14pt;
width: 250px;
}
#settingscog {
cursor: pointer;
margin: 0px 30px;
height: 50%;
filter: invert(100%) sepia(0%) saturate(7465%) hue-rotate(115deg) brightness(116%) contrast(101%);
}
viewport {
position: relative;
display: flex;
flex-flow: row;
flex-wrap: nowrap;
flex-grow: 1;
height: 100%;
overflow-y: scroll;
scrollbar-color: var(--accent-color) var(--primary-color);
scrollbar-width: thin;
}
footer {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
width: 100%;
height: 40px;
align-items: center;
justify-content: center;
background-color: var(--primary-color);
align-content: center;
}
footer > div {
height: 100%;
margin: 0 30px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
cursor: pointer;
}
footer > div > *{
height: 40%;
margin: 0 5px;
}
#madeWith {
flex-grow: 1;
text-align: right;
margin-right: 20px;
cursor: url("media/blahaj.png"), grab;
}
content {
position: relative;
flex-grow: 1;
border-radius: 5px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: start;
align-content: start;
}
#settingsPopup{
z-index: 300;
}
#settingsPopup popup-content{
flex-direction: column;
align-items: start;
margin: 15px 10px;
}
#settingsPopup popup-content > * {
margin: 5px 10px;
}
#settingsPopup popup-content .title {
font-weight: bolder;
}
#addPublication {
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 20px;
position: relative;
}
#addPublication p{
width: 100%;
text-align: center;
font-size: 150pt;
vertical-align: middle;
line-height: 300px;
margin: 0;
color: var(--accent-color);
}
.pill {
flex-grow: 0;
height: 14pt;
font-size: 12pt;
border-radius: 9pt;
background-color: var(--primary-color);
padding: 2pt 17px;
color: black;
}
publication{
cursor: pointer;
background-color: var(--secondary-color);
width: 180px;
height: 300px;
border-radius: 5px;
margin: 10px 10px;
padding: 15px 19px;
position: relative;
flex-shrink: 0;
}
publication::after{
content: '';
position: absolute;
left: 0; top: 0;
border-radius: 5px;
width: 100%; height: 100%;
background: linear-gradient(rgba(0,0,0,0.8), rgba(0, 0, 0, 0.7),rgba(0, 0, 0, 0.2));
}
publication-information {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-details {
display: flex;
flex-direction: column;
justify-content: start;
}
publication-information * {
z-index: 1;
color: var(--accent-color);
}
publication-details * {
z-index: 1;
color: var(--accent-color);
}
connector-name{
width: fit-content;
margin: 10px 0;
}
publication-name{
width: fit-content;
font-size: 16pt;
font-weight: bold;
}
publication-status {
display:block;
height: 10px;
width: 10px;
border-radius: 50%;
margin: 5px;
position: absolute;
top: 5px;
right: 5px;
z-index: 2;
box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 10px, rgb(51, 51, 51) 0px 0px 10px 3px;
}
publication-status::after {
content: attr(release-status);
position: absolute;
top: 0;
right: 0;
visibility: hidden;
/*Text Properties*/
font-size:10pt;
font-weight:bold;
color:white;
text-align: center;
/*Size*/
padding: 3px 8px;
border-radius: 6px;
border: 0px;
background-color: inherit;
}
publication-status:hover::after{
visibility:visible;
}
publication-status[release-status="Ongoing"]{
background-color: limegreen;
}
publication-status[release-status="Completed"]{
background-color: blueviolet;
}
publication-status[release-status="On Hiatus"]{
background-color: darkorange;
}
publication-status[release-status="Cancelled"]{
background-color: firebrick;
}
publication-status[release-status="Upcoming"]{
background-color: aqua;
}
publication-status[release-status="Status Unavailable"]{
background-color: gray;
}
publication img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
border-radius: 5px;
}
popup{
display: none;
width: 100%;
min-height: 100%;
top: 0;
left: 0;
position: fixed;
z-index: 2;
flex-direction: column;
}
popup popup-window {
position: absolute;
z-index: 3;
left: 25%;
top: 100px;
width: 50%;
display: flex;
flex-direction: column;
background-color: var(--second-background-color);
border-radius: 3px;
overflow: hidden;
}
popup popup-window popup-title {
height: 30px;
font-size: 14pt;
font-weight: bolder;
padding: 5px 10px;
margin: 0;
display: flex;
align-items: center;
background-color: var(--primary-color);
color: var(--accent-color)
}
popup popup-window popup-content{
margin: 15px 10px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
popup popup-window popup-content div > * {
margin: 2px 3px 0 0;
}
popup popup-window popup-content input, select {
padding: 3px 4px;
width: 130px;
border: 1px solid lightgrey;
background-color: var(--accent-color);
border-radius: 3px;
}
#newMangaPopup > div {
z-index: 3;
position: relative;
}
#newMangaPopup > #newMangaPopupSelector {
width: 600px;
height: 40px;
margin: 80px auto 0;
}
#newMangaPopup > div > #newMangaConnector, #newMangaTitle, #newMangaTranslatedLanguage {
margin: 0;
display: inline-block;
height: 40px;
}
#newMangaPopup #newMangaConnector {
width: 100px;
padding: 0 0 0 5px;
border-radius: 5px 0 0 5px;
border: 0;
border-right: 1px solid darkgray;
}
#newMangaPopup #newMangaTitle{
width: 445px;
padding: 0 5px 0 5px;
border: 0;
}
#newMangaPopup #newMangaTranslatedLanguage {
width: 45px;
border-radius: 0 5px 5px 0;
border: 0;
border-left: 1px solid darkgray;
margin-left: -5px;
}
#newMangaResult {
display: none;
flex-direction: row;
justify-content: flex-start;
margin: 5px auto 0;
border-radius: 5px;
padding: 5px;
width: min-content;
max-width: 98%;
max-height: 400px;
overflow-x: scroll;
overflow-y: hidden;
}
blur-background {
width: 100%;
height: 100%;
position: absolute;
left: 0;
background: rgba(245, 169, 184, 0.58);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(4.5px);
-webkit-backdrop-filter: blur(4.5px);
}
#publicationViewerPopup{
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 {
display: none;
padding: 2px 4px;
position: fixed;
bottom: 58px;
left: 20px;
background-color: var(--second-background-color);
z-index: 8;
border-radius: 5px;
max-height: 400px;
}
footer-tag-content{
position: relative;
max-height: 400px;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
overflow-y: scroll;
}
footer-tag-content > * {
margin: 2px 5px;
}
footer-tag-popup::before{
content: "";
width: 0;
height: 0;
position: absolute;
border-right: 10px solid var(--second-background-color);
border-left: 10px solid transparent;
border-top: 10px solid var(--second-background-color);
border-bottom: 10px solid transparent;
left: 0;
bottom: -17px;
border-radius: 0 0 0 5px;
}
#loaderdiv {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 200;
}
#loader {
border: 16px solid transparent;
border-top: 16px solid var(--secondary-color);
border-bottom: 16px solid var(--primary-color);
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
position: absolute;
left: calc(50% - 60px);
top: calc(50% - 120px);
z-index: 201;
}
#loaderText {
position: relative;
margin: 0 auto;
top: calc(50% + 80px);
z-index: 201;
text-align: center;
color: var(--second-background-color);
font-size: 20pt;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#jobStatusView {
z-index: 50;
}
#jobStatusView > popup-window {
top: 80px;
width: 50%;
max-height: calc(100% - 140px);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background-color: transparent;
}
#jobStatusView > popup-window > div {
overflow-y: scroll;
overflow-x: hidden;
width: 50%;
margin: 0;
max-height: 100%;
}
#jobStatusView > popup-window > div > div {
overflow-x: hidden;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: 100%;
margin: 0;
}
.jobWrapper {
width: 90%;
margin: 2px 5%;
height: 100px;
position: relative;
flex-shrink: 0;
background-color: rgba(187,187,187,0.4);
border-radius: 3px;
}
.jobWrapper > .jobImage {
height: 90%;
width: 20%;
left: 5px;
object-fit: contain;
position: absolute;
top: 5%;
}
.jobWrapper > .jobTitle {
position: absolute;
left: calc(20% + 10px);
top: 5px;
}
.jobWrapper > .jobProgressBar {
position: absolute;
left: calc(20% + 10px);
bottom: calc(12pt + 10px);
width: calc(80% - 20px);
height: 10px;
}
.jobWrapper > .jobProgressSpan {
position: absolute;
right: 10px;
bottom: calc(12pt + 20px);
width: 60%;
text-align: right;
}
.jobWrapper > .jobCancel {
position: absolute;
right: 10px;
bottom: 5px;
font-size: 12pt;
color: var(--secondary-color);
cursor: pointer;
}