Improve Arr integerations
This commit is contained in:
@@ -17,6 +17,37 @@
|
||||
[data-bs-theme="dark"] .nav-pills .nav-link.active {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.config-item.bg-light {
|
||||
background-color: var(--bs-gray-100) !important;
|
||||
border-left: 4px solid var(--bs-info) !important;
|
||||
}
|
||||
|
||||
.config-item input[readonly] {
|
||||
background-color: var(--bs-gray-200);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.config-item select[readonly] {
|
||||
background-color: var(--bs-gray-200);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Dark mode specific overrides */
|
||||
[data-bs-theme="dark"] .config-item.bg-light {
|
||||
background-color: var(--bs-gray-800) !important;
|
||||
border-left: 4px solid var(--bs-info) !important;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .config-item input[readonly] {
|
||||
background-color: var(--bs-gray-700);
|
||||
color: var(--bs-gray-300);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .config-item select[readonly] {
|
||||
background-color: var(--bs-gray-700);
|
||||
color: var(--bs-gray-300);
|
||||
}
|
||||
</style>
|
||||
<div class="container mt-4">
|
||||
<form id="configForm">
|
||||
@@ -80,7 +111,8 @@
|
||||
<label>
|
||||
<!-- Empty label to keep the button aligned -->
|
||||
</label>
|
||||
<div class="btn btn-primary w-100" onclick="registerMagnetLinkHandler();" id="registerMagnetLink">
|
||||
<div class="btn btn-primary w-100" onclick="registerMagnetLinkHandler();"
|
||||
id="registerMagnetLink">
|
||||
Open Magnet Links in Decypharr
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,7 +135,8 @@
|
||||
id="bindAddress"
|
||||
name="bind_address"
|
||||
placeholder="">
|
||||
<small class="form-text text-muted">Bind address for the application(default is all interface)</small>
|
||||
<small class="form-text text-muted">Bind address for the application(default is all
|
||||
interface)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 mt-3">
|
||||
@@ -150,7 +183,8 @@
|
||||
id="minFileSize"
|
||||
name="min_file_size"
|
||||
placeholder="e.g., 10MB, 1GB">
|
||||
<small class="form-text text-muted">Minimum file size to download (Empty for no limit)</small>
|
||||
<small class="form-text text-muted">Minimum file size to download (Empty for no
|
||||
limit)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mt-3">
|
||||
@@ -161,7 +195,8 @@
|
||||
id="maxFileSize"
|
||||
name="max_file_size"
|
||||
placeholder="e.g., 50GB, 100MB">
|
||||
<small class="form-text text-muted">Maximum file size to download (Empty for no limit)</small>
|
||||
<small class="form-text text-muted">Maximum file size to download (Empty for no
|
||||
limit)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mt-3">
|
||||
@@ -172,13 +207,15 @@
|
||||
id="removeStalledAfter"
|
||||
name="remove_stalled_after"
|
||||
placeholder="e.g., 1m, 30s, 1h">
|
||||
<small class="form-text text-muted">Remove torrents that have been stalled for this duration</small>
|
||||
<small class="form-text text-muted">Remove torrents that have been stalled for this
|
||||
duration</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-primary next-step" data-next="2">Next <i class="bi bi-arrow-right"></i></button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="2">Next <i
|
||||
class="bi bi-arrow-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -196,7 +233,8 @@
|
||||
<button type="button" class="btn btn-outline-secondary prev-step" data-prev="1">
|
||||
<i class="bi bi-arrow-left"></i> Previous
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="3">Next <i class="bi bi-arrow-right"></i></button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="3">Next <i
|
||||
class="bi bi-arrow-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -206,23 +244,31 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label" for="qbit.download_folder">Symlink/Download Folder</label>
|
||||
<input type="text" class="form-control" name="qbit.download_folder" id="qbit.download_folder">
|
||||
<small class="form-text text-muted">Folder where the downloaded files will be stored</small>
|
||||
<input type="text" class="form-control" name="qbit.download_folder"
|
||||
id="qbit.download_folder">
|
||||
<small class="form-text text-muted">Folder where the downloaded files will be
|
||||
stored</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="qbit.refresh_interval">Refresh Interval (seconds)</label>
|
||||
<input type="number" class="form-control" name="qbit.refresh_interval" id="qbit.refresh_interval">
|
||||
<input type="number" class="form-control" name="qbit.refresh_interval"
|
||||
id="qbit.refresh_interval">
|
||||
</div>
|
||||
<div class="col-md-5 mb-3">
|
||||
<label class="form-label" for="qbit.max_downloads">Maximum Downloads Limit</label>
|
||||
<input type="number" class="form-control" name="qbit.max_downloads" id="qbit.max_downloads">
|
||||
<small class="form-text text-muted">Maximum number of simultaneous local downloads across all torrents</small>
|
||||
<input type="number" class="form-control" name="qbit.max_downloads"
|
||||
id="qbit.max_downloads">
|
||||
<small class="form-text text-muted">Maximum number of simultaneous local downloads
|
||||
across all torrents</small>
|
||||
</div>
|
||||
<div class="col mb-3">
|
||||
<div class="form-check me-3 d-inline-block">
|
||||
<input type="checkbox" class="form-check-input" name="qbit.skip_pre_cache" id="qbit.skip_pre_cache">
|
||||
<label class="form-check-label" for="qbit.skip_pre_cache">Disable Pre-Cache On Download</label>
|
||||
<small class="form-text text-muted">Unchecking this caches a tiny part of your file to speed up import</small>
|
||||
<input type="checkbox" class="form-check-input" name="qbit.skip_pre_cache"
|
||||
id="qbit.skip_pre_cache">
|
||||
<label class="form-check-label" for="qbit.skip_pre_cache">Disable Pre-Cache On
|
||||
Download</label>
|
||||
<small class="form-text text-muted">Unchecking this caches a tiny part of your file
|
||||
to speed up import</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -231,7 +277,8 @@
|
||||
<button type="button" class="btn btn-outline-secondary prev-step" data-prev="2">
|
||||
<i class="bi bi-arrow-left"></i> Previous
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="4">Next <i class="bi bi-arrow-right"></i></button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="4">Next <i
|
||||
class="bi bi-arrow-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -249,7 +296,8 @@
|
||||
<button type="button" class="btn btn-outline-secondary prev-step" data-prev="3">
|
||||
<i class="bi bi-arrow-left"></i> Previous
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="5">Next <i class="bi bi-arrow-right"></i></button>
|
||||
<button type="button" class="btn btn-primary next-step" data-next="5">Next <i
|
||||
class="bi bi-arrow-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -259,7 +307,8 @@
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="form-check me-3 d-inline-block">
|
||||
<input type="checkbox" class="form-check-input" name="repair.enabled" id="repair.enabled">
|
||||
<input type="checkbox" class="form-check-input" name="repair.enabled"
|
||||
id="repair.enabled">
|
||||
<label class="form-check-label" for="repair.enabled">Enable Scheduled Repair</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -268,34 +317,43 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label" for="repair.interval">Scheduled Interval</label>
|
||||
<input type="text" class="form-control" name="repair.interval" id="repair.interval" placeholder="e.g., 24h">
|
||||
<small class="form-text text-muted">Interval for the repair process(e.g., 24h, 1d, 03:00, or a crontab)</small>
|
||||
<input type="text" class="form-control" name="repair.interval" id="repair.interval"
|
||||
placeholder="e.g., 24h">
|
||||
<small class="form-text text-muted">Interval for the repair process(e.g., 24h, 1d,
|
||||
03:00, or a crontab)</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="repair.workers">Workers</label>
|
||||
<input type="text" class="form-control" name="repair.workers" id="repair.workers">
|
||||
<small class="form-text text-muted">Number of workers to use for the repair process</small>
|
||||
<small class="form-text text-muted">Number of workers to use for the repair
|
||||
process</small>
|
||||
</div>
|
||||
<div class="col-md-5 mb-3">
|
||||
<label class="form-label" for="repair.zurg_url">Zurg URL</label>
|
||||
<input type="text" class="form-control" name="repair.zurg_url" id="repair.zurg_url" placeholder="http://zurg:9999">
|
||||
<small class="form-text text-muted">If you have Zurg running, you can use it to speed up the repair process</small>
|
||||
<input type="text" class="form-control" name="repair.zurg_url" id="repair.zurg_url"
|
||||
placeholder="http://zurg:9999">
|
||||
<small class="form-text text-muted">If you have Zurg running, you can use it to
|
||||
speed up the repair process</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="repair.use_webdav" id="repair.use_webdav">
|
||||
<input type="checkbox" class="form-check-input" name="repair.use_webdav"
|
||||
id="repair.use_webdav">
|
||||
<label class="form-check-label" for="repair.use_webdav">Use Webdav</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Use Internal Webdav for repair(make sure webdav is enabled in the debrid section</small>
|
||||
<small class="form-text text-muted">Use Internal Webdav for repair(make sure webdav
|
||||
is enabled in the debrid section</small>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="repair.auto_process" id="repair.auto_process">
|
||||
<input type="checkbox" class="form-check-input" name="repair.auto_process"
|
||||
id="repair.auto_process">
|
||||
<label class="form-check-label" for="repair.auto_process">Auto Process</label>
|
||||
</div>
|
||||
<small class="form-text text-muted">Automatically process the repair job(delete broken symlinks and searches the arr again)</small>
|
||||
<small class="form-text text-muted">Automatically process the repair job(delete
|
||||
broken symlinks and searches the arr again)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -335,15 +393,44 @@
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].api_key" >API Key</label>
|
||||
<input type="password" class="form-control" name="debrid[${index}].api_key" id="debrid[${index}].api_key" required>
|
||||
<div class="password-toggle-container">
|
||||
<input type="password"
|
||||
class="form-control has-toggle"
|
||||
name="debrid[${index}].api_key"
|
||||
id="debrid[${index}].api_key"
|
||||
required>
|
||||
<button type="button"
|
||||
class="password-toggle-btn"
|
||||
onclick="togglePassword('debrid[${index}].api_key');">
|
||||
<i class="bi bi-eye" id="debrid[${index}].api_key_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<small class="form-text text-muted">API Key for the debrid service</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].download_api_keys">Download API Keys</label>
|
||||
<div class="password-toggle-container">
|
||||
<textarea class="form-control has-toggle"
|
||||
name="debrid[${index}].download_api_keys"
|
||||
id="debrid[${index}].download_api_keys"
|
||||
rows="3"
|
||||
style="font-family: monospace; resize: vertical;"
|
||||
placeholder="Enter one API key per line key1 key2 key3"></textarea>
|
||||
<button type="button"
|
||||
class="password-toggle-btn"
|
||||
style="top: 20px;"
|
||||
onclick="togglePasswordTextarea('debrid[${index}].download_api_keys');">
|
||||
<i class="bi bi-eye" id="debrid[${index}].download_api_keys_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<small class="form-text text-muted">Multiple API keys for download (one per line). If empty, main API key will be used.</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].folder">Mount/Rclone Folder</label>
|
||||
<input type="text" class="form-control" name="debrid[${index}].folder" id="debrid[${index}].folder" placeholder="e.g. /mnt/remote/realdebrid" required>
|
||||
<small class="form-text text-muted">Path to where you've mounted the debrid files. Usually your rclone path</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].rate_limit" >Rate Limit</label>
|
||||
<input type="text" class="form-control" name="debrid[${index}].rate_limit" id="debrid[${index}].rate_limit" placeholder="e.g., 200/minute" value="250/minute">
|
||||
<small class="form-text text-muted">Rate limit for the debrid service. Confirm your debrid service rate limit</small>
|
||||
@@ -432,7 +519,17 @@
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<label class="form-label" for="debrid[${index}].rc_pass">Rclone RC Password</label>
|
||||
<input type="password" class="form-control webdav-field" name="debrid[${index}].rc_pass" id="debrid[${index}].rc_pass">
|
||||
<div class="password-toggle-container">
|
||||
<input type="password"
|
||||
class="form-control webdav-field has-toggle"
|
||||
name="debrid[${index}].rc_pass"
|
||||
id="debrid[${index}].rc_pass">
|
||||
<button type="button"
|
||||
class="password-toggle-btn"
|
||||
onclick="togglePassword('debrid[${index}].rc_pass');">
|
||||
<i class="bi bi-eye" id="debrid[${index}].rc_pass_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<small class="form-text text-muted">Rclone RC Password for the webdav server</small>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
@@ -538,7 +635,7 @@
|
||||
const filterTemplate = (debridIndex, dirIndex, filterIndex, filterType) => {
|
||||
let placeholder, label;
|
||||
|
||||
switch(filterType) {
|
||||
switch (filterType) {
|
||||
case 'include':
|
||||
placeholder = "Text that should be included in filename";
|
||||
label = "Include";
|
||||
@@ -632,58 +729,87 @@
|
||||
`;
|
||||
};
|
||||
|
||||
const arrTemplate = (index) => `
|
||||
<div class="config-item position-relative mb-3 p-3 border rounded">
|
||||
<button type="button" class="btn btn-sm btn-danger position-absolute top-0 end-0 m-2"
|
||||
onclick="if(confirm('Are you sure you want to delete this arr?')) this.closest('.config-item').remove();"
|
||||
title="Delete this arr">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" name="arr[${index}].name" id="arr[${index}].name" required>
|
||||
const arrTemplate = (index, data = {}) => `
|
||||
<div class="config-item position-relative mb-3 p-3 border rounded ${data.source === 'auto' ? 'bg-light' : ''}">
|
||||
${data.source !== 'auto' ? `
|
||||
<button type="button" class="btn btn-sm btn-danger position-absolute top-0 end-0 m-2"
|
||||
onclick="if(confirm('Are you sure you want to delete this arr?')) this.closest('.config-item').remove();"
|
||||
title="Delete this arr">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
` : `
|
||||
<div class="position-absolute top-0 end-0 m-2">
|
||||
<span class="badge bg-info">Auto-detected</span>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].host" class="form-label">Host</label>
|
||||
<input type="text" class="form-control" name="arr[${index}].host" id="arr[${index}].host" required>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for"arr[${index}].token" class="form-label">API Token</label>
|
||||
<input type="password" class="form-control" name="arr[${index}].token" id="arr[${index}].token" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<select class="form-select" name="arr[${index}].selected_debrid" id="arr[${index}].selected_debrid">
|
||||
<option value="" selected disabled>Select Arr Debrid</option>
|
||||
<option value="realdebrid">Real Debrid</option>
|
||||
<option value="alldebrid">AllDebrid</option>
|
||||
<option value="debrid_link">Debrid Link</option>
|
||||
<option value="torbox">Torbox</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].cleanup" class="form-check-label">Cleanup Queue</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].cleanup" id="arr[${index}].cleanup">
|
||||
`}
|
||||
<div class="row">
|
||||
<input type="hidden" name="arr[${index}].source" value="${data.source || ''}">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].name" class="form-label">Name</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="arr[${index}].name"
|
||||
id="arr[${index}].name"
|
||||
${data.source === 'auto' ? 'readonly' : 'required'}>
|
||||
${data.source === 'auto' ? '<input type="hidden" name="arr[' + index + '].source" value="auto">' : ''}
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].host" class="form-label">Host</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="arr[${index}].host"
|
||||
id="arr[${index}].host"
|
||||
${data.source === 'auto' ? 'readonly' : 'required'}>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].token" class="form-label">API Token</label>
|
||||
<div class="password-toggle-container">
|
||||
<input type="password"
|
||||
class="form-control has-toggle"
|
||||
name="arr[${index}].token"
|
||||
id="arr[${index}].token"
|
||||
${data.source === 'auto' ? 'readonly' : 'required'}>
|
||||
<button type="button"
|
||||
class="password-toggle-btn"
|
||||
onclick="togglePassword('arr[${index}].token');"
|
||||
${data.source === 'auto' ? 'disabled style="opacity: 0.5;"' : ''}>
|
||||
<i class="bi bi-eye" id="arr[${index}].token_icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].skip_repair" class="form-check-label">Skip Repair</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].skip_repair" id="arr[${index}].skip_repair">
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="arr[${index}].selected_debrid" class="form-label">Select Arr Debrid</label>
|
||||
<select class="form-select" name="arr[${index}].selected_debrid" id="arr[${index}].selected_debrid">
|
||||
<option value="" selected disabled>Select Arr Debrid</option>
|
||||
<option value="realdebrid">Real Debrid</option>
|
||||
<option value="alldebrid">AllDebrid</option>
|
||||
<option value="debrid_link">Debrid Link</option>
|
||||
<option value="torbox">Torbox</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].download_uncached" class="form-check-label">Download Uncached</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].download_uncached" id="arr[${index}].download_uncached">
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].cleanup" class="form-check-label">Cleanup Queue</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].cleanup" id="arr[${index}].cleanup">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].skip_repair" class="form-check-label">Skip Repair</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].skip_repair" id="arr[${index}].skip_repair">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 mb-3">
|
||||
<div class="form-check">
|
||||
<label for="arr[${index}].download_uncached" class="form-check-label">Download Uncached</label>
|
||||
<input type="checkbox" class="form-check-input" name="arr[${index}].download_uncached" id="arr[${index}].download_uncached">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`;
|
||||
|
||||
const debridDirectoryCounts = {};
|
||||
const directoryFilterCounts = {};
|
||||
@@ -739,6 +865,7 @@
|
||||
debridDirectoryCounts[debridIndex]++;
|
||||
return dirIndex;
|
||||
}
|
||||
|
||||
function addFilter(debridIndex, dirIndex, filterType, filterValue = "") {
|
||||
const dirKey = `${debridIndex}-${dirIndex}`;
|
||||
if (!directoryFilterCounts[dirKey]) {
|
||||
@@ -771,7 +898,7 @@
|
||||
}
|
||||
|
||||
// Main functionality
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let debridCount = 0;
|
||||
let arrCount = 0;
|
||||
let currentStep = 1;
|
||||
@@ -785,21 +912,21 @@
|
||||
|
||||
// Step navigation
|
||||
document.querySelectorAll('.nav-link').forEach(navLink => {
|
||||
navLink.addEventListener('click', function() {
|
||||
navLink.addEventListener('click', function () {
|
||||
const stepNumber = parseInt(this.getAttribute('data-step'));
|
||||
goToStep(stepNumber);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.next-step').forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
button.addEventListener('click', function () {
|
||||
const nextStep = parseInt(this.getAttribute('data-next'));
|
||||
goToStep(nextStep);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.prev-step').forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
button.addEventListener('click', function () {
|
||||
const prevStep = parseInt(this.getAttribute('data-prev'));
|
||||
goToStep(prevStep);
|
||||
});
|
||||
@@ -910,7 +1037,7 @@
|
||||
addArrConfig();
|
||||
});
|
||||
|
||||
$(document).on('change', '.useWebdav', function() {
|
||||
$(document).on('change', '.useWebdav', function () {
|
||||
const webdavConfig = $(this).closest('.config-item').find(`.webdav`);
|
||||
if (webdavConfig.length === 0) return;
|
||||
|
||||
@@ -953,7 +1080,7 @@
|
||||
// Save config logic
|
||||
const response = await fetcher('/api/config', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
|
||||
@@ -1005,7 +1132,7 @@
|
||||
|
||||
if (data.use_webdav && data.directories) {
|
||||
Object.entries(data.directories).forEach(([dirName, dirData]) => {
|
||||
const dirIndex = addDirectory(debridCount, { name: dirName });
|
||||
const dirIndex = addDirectory(debridCount, {name: dirName});
|
||||
|
||||
// Add filters if available
|
||||
if (dirData.filters) {
|
||||
@@ -1015,6 +1142,20 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (data.download_api_keys && Array.isArray(data.download_api_keys)) {
|
||||
const downloadKeysTextarea = container.querySelector(`[name="debrid[${debridCount}].download_api_keys"]`);
|
||||
if (downloadKeysTextarea) {
|
||||
downloadKeysTextarea.value = data.download_api_keys.join('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const downloadKeysTextarea = newDebrid.querySelector(`[name="debrid[${debridCount}].download_api_keys"]`);
|
||||
if (downloadKeysTextarea) {
|
||||
downloadKeysTextarea.style.webkitTextSecurity = 'disc';
|
||||
downloadKeysTextarea.style.textSecurity = 'disc';
|
||||
downloadKeysTextarea.setAttribute('data-password-visible', 'false');
|
||||
}
|
||||
|
||||
debridCount++;
|
||||
@@ -1022,11 +1163,10 @@
|
||||
|
||||
function addArrConfig(data = {}) {
|
||||
const container = document.getElementById('arrConfigs');
|
||||
container.insertAdjacentHTML('beforeend', arrTemplate(arrCount));
|
||||
container.insertAdjacentHTML('beforeend', arrTemplate(arrCount, data));
|
||||
|
||||
// Add a delete button to the new arr
|
||||
// Don't add delete button for auto-detected arrs since it's already handled in template
|
||||
const newArr = container.lastElementChild;
|
||||
addDeleteButton(newArr, `Delete this arr`);
|
||||
|
||||
if (data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
@@ -1051,7 +1191,7 @@
|
||||
deleteBtn.innerHTML = '<i class="bi bi-trash"></i>';
|
||||
deleteBtn.title = tooltip;
|
||||
|
||||
deleteBtn.addEventListener('click', function() {
|
||||
deleteBtn.addEventListener('click', function () {
|
||||
if (confirm('Are you sure you want to delete this item?')) {
|
||||
element.remove();
|
||||
}
|
||||
@@ -1126,7 +1266,7 @@
|
||||
const nameInput = document.querySelector(`[name="debrid[${i}].directory[${j}].name"]`);
|
||||
if (nameInput && nameInput.value) {
|
||||
const dirName = nameInput.value;
|
||||
debrid.directories[dirName] = { filters: {} };
|
||||
debrid.directories[dirName] = {filters: {}};
|
||||
|
||||
// Get directory key for filter counting
|
||||
const dirKey = `${i}-${j}`;
|
||||
@@ -1146,6 +1286,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
let downloadApiKeysTextarea = document.querySelector(`[name="debrid[${i}].download_api_keys"]`);
|
||||
if (downloadApiKeysTextarea && downloadApiKeysTextarea.value.trim()) {
|
||||
debrid.download_api_keys = downloadApiKeysTextarea.value
|
||||
.split('\n')
|
||||
.map(key => key.trim())
|
||||
.filter(key => key.length > 0);
|
||||
}
|
||||
|
||||
if (debrid.name && debrid.api_key) {
|
||||
config.debrids.push(debrid);
|
||||
}
|
||||
@@ -1163,7 +1311,8 @@
|
||||
cleanup: document.querySelector(`[name="arr[${i}].cleanup"]`).checked,
|
||||
skip_repair: document.querySelector(`[name="arr[${i}].skip_repair"]`).checked,
|
||||
download_uncached: document.querySelector(`[name="arr[${i}].download_uncached"]`).checked,
|
||||
selectedDebrid: document.querySelector(`[name="arr[${i}].selected_debrid"]`).value
|
||||
selected_debrid: document.querySelector(`[name="arr[${i}].selected_debrid"]`).value,
|
||||
source: document.querySelector(`[name="arr[${i}].source"]`).value
|
||||
};
|
||||
|
||||
if (arr.name && arr.host) {
|
||||
|
||||
Reference in New Issue
Block a user