diff --git a/roles/hysteria2/templates/export/global-index.html.j2 b/roles/hysteria2/templates/export/global-index.html.j2
index 1da825e..8829461 100644
--- a/roles/hysteria2/templates/export/global-index.html.j2
+++ b/roles/hysteria2/templates/export/global-index.html.j2
@@ -313,6 +313,34 @@
font-size: 0.75rem;
color: var(--muted);
}
+ .lightbox-actions {
+ margin-top: 1rem;
+ display: flex;
+ justify-content: center;
+ }
+ .lightbox-download {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.55rem 1rem;
+ border-radius: 999px;
+ border: 1px solid var(--border);
+ background: var(--bg-input);
+ color: var(--accent);
+ text-decoration: none;
+ font-size: 0.85rem;
+ font-weight: 650;
+ transition: color 0.15s, border-color 0.15s, background 0.15s;
+ }
+ .lightbox-download:hover {
+ border-color: var(--accent);
+ background: var(--accent-soft);
+ }
+ .lightbox-download svg {
+ width: 16px;
+ height: 16px;
+ flex-shrink: 0;
+ }
.lightbox-close {
position: absolute;
top: 0.65rem;
@@ -459,6 +487,7 @@
tabindex="0"
data-lightbox-src="{{ server.dir | e }}/{{ user.name | e }}.png"
data-lightbox-caption="{{ server.name | e }} · {{ user.name | e }}"
+ data-lightbox-download="{{ server.name | e }}-{{ user.name | e }}.png"
aria-label="Открыть QR-код {{ user.name | e }}"
>
@@ -487,6 +516,12 @@
Клик вне QR или Esc — закрыть
@@ -521,11 +556,15 @@ var img = document.getElementById('lightbox-img'); var caption = document.getElementById('lightbox-caption'); var closeBtn = document.getElementById('lightbox-close'); + var downloadBtn = document.getElementById('lightbox-download'); - function openLightbox(src, text, alt) { + function openLightbox(src, text, alt, filename) { img.src = src; img.alt = alt || text || 'QR'; caption.textContent = text || ''; + downloadBtn.href = src; + downloadBtn.setAttribute('download', filename || 'qr.png'); + downloadBtn.setAttribute('aria-label', 'Скачать ' + (filename || 'qr.png')); box.classList.add('open'); box.setAttribute('aria-hidden', 'false'); document.body.classList.add('lightbox-open'); @@ -537,11 +576,17 @@ box.setAttribute('aria-hidden', 'true'); document.body.classList.remove('lightbox-open'); img.removeAttribute('src'); + downloadBtn.removeAttribute('href'); } document.querySelectorAll('[data-lightbox-src]').forEach(function (el) { function openFromEl() { - openLightbox(el.getAttribute('data-lightbox-src'), el.getAttribute('data-lightbox-caption'), el.getAttribute('alt')); + openLightbox( + el.getAttribute('data-lightbox-src'), + el.getAttribute('data-lightbox-caption'), + el.getAttribute('alt'), + el.getAttribute('data-lightbox-download') + ); } el.addEventListener('click', openFromEl); el.addEventListener('keydown', function (e) { diff --git a/roles/hysteria2/templates/export/index.html.j2 b/roles/hysteria2/templates/export/index.html.j2 index 9c843a2..6a5d469 100644 --- a/roles/hysteria2/templates/export/index.html.j2 +++ b/roles/hysteria2/templates/export/index.html.j2 @@ -244,6 +244,34 @@ font-size: 0.75rem; color: var(--muted); } + .lightbox-actions { + margin-top: 1rem; + display: flex; + justify-content: center; + } + .lightbox-download { + display: inline-flex; + align-items: center; + gap: 0.45rem; + padding: 0.55rem 1rem; + border-radius: 999px; + border: 1px solid var(--border); + background: var(--bg-input); + color: var(--accent); + text-decoration: none; + font-size: 0.85rem; + font-weight: 650; + transition: color 0.15s, border-color 0.15s, background 0.15s; + } + .lightbox-download:hover { + border-color: var(--accent); + background: var(--accent-soft); + } + .lightbox-download svg { + width: 16px; + height: 16px; + flex-shrink: 0; + } .lightbox-close { position: absolute; top: 0.65rem; @@ -381,6 +409,7 @@ tabindex="0" data-lightbox-src="{{ user.name | e }}.png" data-lightbox-caption="{{ user.name | e }}" + data-lightbox-download="{{ hysteria2_output_name | e }}-{{ user.name | e }}.png" aria-label="Открыть QR-код {{ user.name | e }}" > @@ -409,6 +438,12 @@Клик вне QR или Esc — закрыть
@@ -443,11 +478,15 @@ var img = document.getElementById('lightbox-img'); var caption = document.getElementById('lightbox-caption'); var closeBtn = document.getElementById('lightbox-close'); + var downloadBtn = document.getElementById('lightbox-download'); - function openLightbox(src, text, alt) { + function openLightbox(src, text, alt, filename) { img.src = src; img.alt = alt || text || 'QR'; caption.textContent = text || ''; + downloadBtn.href = src; + downloadBtn.setAttribute('download', filename || 'qr.png'); + downloadBtn.setAttribute('aria-label', 'Скачать ' + (filename || 'qr.png')); box.classList.add('open'); box.setAttribute('aria-hidden', 'false'); document.body.classList.add('lightbox-open'); @@ -459,11 +498,17 @@ box.setAttribute('aria-hidden', 'true'); document.body.classList.remove('lightbox-open'); img.removeAttribute('src'); + downloadBtn.removeAttribute('href'); } document.querySelectorAll('[data-lightbox-src]').forEach(function (el) { function openFromEl() { - openLightbox(el.getAttribute('data-lightbox-src'), el.getAttribute('data-lightbox-caption'), el.getAttribute('alt')); + openLightbox( + el.getAttribute('data-lightbox-src'), + el.getAttribute('data-lightbox-caption'), + el.getAttribute('alt'), + el.getAttribute('data-lightbox-download') + ); } el.addEventListener('click', openFromEl); el.addEventListener('keydown', function (e) {