343 lines
12 KiB
HTML
343 lines
12 KiB
HTML
{{ define "layout" }}
|
|
<!DOCTYPE html>
|
|
<html lang="en" data-bs-theme="light">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Decypharr - {{.Title}}</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet"/>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css"/>
|
|
<style>
|
|
:root {
|
|
--primary-color: #2563eb;
|
|
--secondary-color: #1e40af;
|
|
--bg-color: #f8fafc;
|
|
--card-bg: #ffffff;
|
|
--text-color: #333333;
|
|
--card-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
--nav-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
--border-color: #e5e7eb;
|
|
}
|
|
|
|
[data-bs-theme="dark"] {
|
|
--primary-color: #3b82f6;
|
|
--secondary-color: #60a5fa;
|
|
--bg-color: #1e293b;
|
|
--card-bg: #283548;
|
|
--text-color: #e5e7eb;
|
|
--card-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
|
|
--nav-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
--border-color: #4b5563;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--bg-color);
|
|
color: var(--text-color);
|
|
transition: background-color 0.3s ease, color 0.3s ease;
|
|
}
|
|
|
|
.navbar {
|
|
padding: 1rem 0;
|
|
background: var(--card-bg) !important;
|
|
box-shadow: var(--nav-shadow);
|
|
border-bottom: 1px solid var(--border-color);
|
|
}
|
|
|
|
.navbar-brand {
|
|
color: var(--primary-color) !important;
|
|
font-weight: 700;
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.card {
|
|
border: none;
|
|
border-radius: 10px;
|
|
box-shadow: var(--card-shadow);
|
|
background-color: var(--card-bg);
|
|
}
|
|
|
|
.nav-link {
|
|
padding: 0.5rem 1rem;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.nav-link.active {
|
|
color: var(--primary-color) !important;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.table {
|
|
color: var(--text-color);
|
|
}
|
|
|
|
/* Dark mode specific overrides */
|
|
[data-bs-theme="dark"] .navbar-light .navbar-toggler-icon {
|
|
filter: invert(1);
|
|
}
|
|
|
|
[data-bs-theme="dark"] .form-control,
|
|
[data-bs-theme="dark"] .form-select {
|
|
background-color: #374151;
|
|
color: #e5e7eb;
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
[data-bs-theme="dark"] .form-control:focus,
|
|
[data-bs-theme="dark"] .form-select:focus {
|
|
border-color: var(--primary-color);
|
|
}
|
|
|
|
/* Theme toggle button styles */
|
|
.theme-toggle {
|
|
cursor: pointer;
|
|
padding: 0.5rem;
|
|
border-radius: 50%;
|
|
width: 38px;
|
|
height: 38px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
.theme-toggle:hover {
|
|
background-color: rgba(128, 128, 128, 0.2);
|
|
}
|
|
</style>
|
|
<script>
|
|
(function() {
|
|
const savedTheme = localStorage.getItem('theme');
|
|
if (savedTheme) {
|
|
document.documentElement.setAttribute('data-bs-theme', savedTheme);
|
|
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
document.documentElement.setAttribute('data-bs-theme', 'dark');
|
|
} else {
|
|
document.documentElement.setAttribute('data-bs-theme', 'light');
|
|
}
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
|
<!-- Toast messages will be created dynamically here -->
|
|
</div>
|
|
<nav class="navbar navbar-expand-lg navbar-light mb-4">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="/">
|
|
<i class="bi bi-cloud-download me-2"></i>Decypharr
|
|
</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav me-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link {{if eq .Page "index"}}active{{end}}" href="{{.URLBase}}">
|
|
<i class="bi bi-table me-1"></i>Torrents
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {{if eq .Page "download"}}active{{end}}" href="{{.URLBase}}download">
|
|
<i class="bi bi-cloud-download me-1"></i>Download
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {{if eq .Page "repair"}}active{{end}}" href="{{.URLBase}}repair">
|
|
<i class="bi bi-tools me-1"></i>Repair
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {{if eq .Page "config"}}active{{end}}" href="{{.URLBase}}config">
|
|
<i class="bi bi-gear me-1"></i>Settings
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="{{.URLBase}}webdav" target="_blank">
|
|
<i class="bi bi-cloud me-1"></i>WebDAV
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="{{.URLBase}}logs" target="_blank">
|
|
<i class="bi bi-journal me-1"></i>Logs
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<div class="d-flex align-items-center">
|
|
<div class="theme-toggle me-3" id="themeToggle" title="Toggle dark mode">
|
|
<i class="bi bi-sun-fill" id="lightIcon"></i>
|
|
<i class="bi bi-moon-fill d-none" id="darkIcon"></i>
|
|
</div>
|
|
<a href="{{.URLBase}}stats" class="me-2">
|
|
<i class="bi bi-bar-chart-line me-1"></i>Stats
|
|
</a>
|
|
<span class="badge bg-primary" id="version-badge">Loading...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
{{ if eq .Page "index" }}
|
|
{{ template "index" . }}
|
|
{{ else if eq .Page "download" }}
|
|
{{ template "download" . }}
|
|
{{ else if eq .Page "repair" }}
|
|
{{ template "repair" . }}
|
|
{{ else if eq .Page "config" }}
|
|
{{ template "config" . }}
|
|
{{ else if eq .Page "login" }}
|
|
{{ template "login" . }}
|
|
{{ else if eq .Page "register" }}
|
|
{{ template "register" . }}
|
|
{{ else }}
|
|
{{ end }}
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
|
<script>
|
|
|
|
window.urlBase = "{{.URLBase}}";
|
|
|
|
function joinURL(base, path) {
|
|
if (!base.endsWith('/')) {
|
|
base += '/';
|
|
}
|
|
if (path.startsWith('/')) {
|
|
path = path.substring(1);
|
|
}
|
|
return base + path;
|
|
|
|
}
|
|
|
|
function fetcher(endpoint, options = {}) {
|
|
// Use the global urlBase or default to empty string
|
|
let baseUrl = window.urlBase || '';
|
|
|
|
let url = joinURL(baseUrl, endpoint);
|
|
|
|
// Return the regular fetcher with the complete URL
|
|
return fetch(url, options);
|
|
}
|
|
/**
|
|
* Create a toast message
|
|
* @param {string} message - The message to display
|
|
* @param {string} [type='success'] - The type of toast (success, warning, error)
|
|
*/
|
|
const createToast = (message, type = 'success') => {
|
|
type = ['success', 'warning', 'error'].includes(type) ? type : 'success';
|
|
|
|
const toastTimeouts = {
|
|
success: 5000,
|
|
warning: 10000,
|
|
error: 15000
|
|
};
|
|
|
|
const toastContainer = document.querySelector('.toast-container');
|
|
const toastId = `toast-${Date.now()}`;
|
|
|
|
const toastHtml = `
|
|
<div id="${toastId}" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
|
<div class="toast-header ${type === 'error' ? 'bg-danger text-white' : type === 'warning' ? 'bg-warning text-dark' : 'bg-success text-white'}">
|
|
<strong class="me-auto">
|
|
${type === 'error' ? 'Error' : type === 'warning' ? 'Warning' : 'Success'}
|
|
</strong>
|
|
<button type="button" class="btn-close ${type === 'warning' ? '' : 'btn-close-white'}" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
<div class="toast-body">
|
|
${message.replace(/\n/g, '<br>')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
|
|
|
|
const toastElement = document.getElementById(toastId);
|
|
const toast = new bootstrap.Toast(toastElement, {
|
|
autohide: true,
|
|
delay: toastTimeouts[type]
|
|
|
|
});
|
|
|
|
toast.show();
|
|
|
|
toastElement.addEventListener('hidden.bs.toast', () => {
|
|
toastElement.remove();
|
|
});
|
|
};
|
|
|
|
// Theme management
|
|
const themeToggle = document.getElementById('themeToggle');
|
|
const lightIcon = document.getElementById('lightIcon');
|
|
const darkIcon = document.getElementById('darkIcon');
|
|
const htmlElement = document.documentElement;
|
|
|
|
// Function to set the theme
|
|
function setTheme(theme) {
|
|
htmlElement.setAttribute('data-bs-theme', theme);
|
|
localStorage.setItem('theme', theme);
|
|
|
|
if (theme === 'dark') {
|
|
lightIcon.classList.add('d-none');
|
|
darkIcon.classList.remove('d-none');
|
|
} else {
|
|
lightIcon.classList.remove('d-none');
|
|
darkIcon.classList.add('d-none');
|
|
}
|
|
}
|
|
|
|
// Check for saved theme preference or use system preference
|
|
const savedTheme = localStorage.getItem('theme');
|
|
|
|
if (savedTheme) {
|
|
setTheme(savedTheme);
|
|
} else {
|
|
// Check for system preference
|
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
setTheme('dark');
|
|
} else {
|
|
setTheme('light');
|
|
}
|
|
}
|
|
|
|
// Toggle theme when button is clicked
|
|
themeToggle.addEventListener('click', () => {
|
|
const currentTheme = htmlElement.getAttribute('data-bs-theme');
|
|
setTheme(currentTheme === 'dark' ? 'light' : 'dark');
|
|
});
|
|
|
|
// Listen for system theme changes
|
|
if (window.matchMedia) {
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
|
if (!localStorage.getItem('theme')) {
|
|
setTheme(e.matches ? 'dark' : 'light');
|
|
}
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
fetcher('/version')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
const versionBadge = document.getElementById('version-badge');
|
|
|
|
// Add url to version badge
|
|
versionBadge.innerHTML = `<a href="https://github.com/sirrobot01/debrid-blackhole/releases/tag/${data.version}" target="_blank" class="text-white">${data.channel}-${data.version}</a>`;
|
|
|
|
|
|
if (data.channel === 'beta') {
|
|
versionBadge.classList.add('beta');
|
|
} else if (data.channel === 'nightly') {
|
|
versionBadge.classList.add('nightly');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching version:', error);
|
|
document.getElementById('version-badge').textContent = 'Unknown';
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|
|
{{ end }} |