Добавить кнопку скачивания QR в lightbox
Файл сохраняется как <сервер>-<пользователь>.png. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -302,6 +302,34 @@
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--muted);
|
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 {
|
.lightbox-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.65rem;
|
top: 0.65rem;
|
||||||
@@ -436,6 +464,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
data-lightbox-src="{{ server.dir | e }}/{{ user.name | e }}.png"
|
data-lightbox-src="{{ server.dir | e }}/{{ user.name | e }}.png"
|
||||||
data-lightbox-caption="{{ server.name | e }} · {{ user.name | e }}"
|
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 }}"
|
aria-label="Открыть QR-код {{ user.name | e }}"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -464,6 +493,12 @@
|
|||||||
<button type="button" class="lightbox-close" id="lightbox-close" aria-label="Закрыть">×</button>
|
<button type="button" class="lightbox-close" id="lightbox-close" aria-label="Закрыть">×</button>
|
||||||
<img id="lightbox-img" src="" alt="">
|
<img id="lightbox-img" src="" alt="">
|
||||||
<p class="lightbox-caption" id="lightbox-caption"></p>
|
<p class="lightbox-caption" id="lightbox-caption"></p>
|
||||||
|
<div class="lightbox-actions">
|
||||||
|
<a class="lightbox-download" id="lightbox-download" href="#" download>
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||||
|
Скачать QR
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<p class="lightbox-hint">Клик вне QR или Esc — закрыть</p>
|
<p class="lightbox-hint">Клик вне QR или Esc — закрыть</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -498,11 +533,15 @@
|
|||||||
var img = document.getElementById('lightbox-img');
|
var img = document.getElementById('lightbox-img');
|
||||||
var caption = document.getElementById('lightbox-caption');
|
var caption = document.getElementById('lightbox-caption');
|
||||||
var closeBtn = document.getElementById('lightbox-close');
|
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.src = src;
|
||||||
img.alt = alt || text || 'QR';
|
img.alt = alt || text || 'QR';
|
||||||
caption.textContent = text || '';
|
caption.textContent = text || '';
|
||||||
|
downloadBtn.href = src;
|
||||||
|
downloadBtn.setAttribute('download', filename || 'qr.png');
|
||||||
|
downloadBtn.setAttribute('aria-label', 'Скачать ' + (filename || 'qr.png'));
|
||||||
box.classList.add('open');
|
box.classList.add('open');
|
||||||
box.setAttribute('aria-hidden', 'false');
|
box.setAttribute('aria-hidden', 'false');
|
||||||
document.body.classList.add('lightbox-open');
|
document.body.classList.add('lightbox-open');
|
||||||
@@ -514,11 +553,17 @@
|
|||||||
box.setAttribute('aria-hidden', 'true');
|
box.setAttribute('aria-hidden', 'true');
|
||||||
document.body.classList.remove('lightbox-open');
|
document.body.classList.remove('lightbox-open');
|
||||||
img.removeAttribute('src');
|
img.removeAttribute('src');
|
||||||
|
downloadBtn.removeAttribute('href');
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll('[data-lightbox-src]').forEach(function (el) {
|
document.querySelectorAll('[data-lightbox-src]').forEach(function (el) {
|
||||||
function openFromEl() {
|
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('click', openFromEl);
|
||||||
el.addEventListener('keydown', function (e) {
|
el.addEventListener('keydown', function (e) {
|
||||||
|
|||||||
@@ -235,6 +235,34 @@
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--muted);
|
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 {
|
.lightbox-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.65rem;
|
top: 0.65rem;
|
||||||
@@ -361,6 +389,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
data-lightbox-src="{{ user.name | e }}.png"
|
data-lightbox-src="{{ user.name | e }}.png"
|
||||||
data-lightbox-caption="{{ user.name | e }}"
|
data-lightbox-caption="{{ user.name | e }}"
|
||||||
|
data-lightbox-download="{{ hysteria2_output_name | e }}-{{ user.name | e }}.png"
|
||||||
aria-label="Открыть QR-код {{ user.name | e }}"
|
aria-label="Открыть QR-код {{ user.name | e }}"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -389,6 +418,12 @@
|
|||||||
<button type="button" class="lightbox-close" id="lightbox-close" aria-label="Закрыть">×</button>
|
<button type="button" class="lightbox-close" id="lightbox-close" aria-label="Закрыть">×</button>
|
||||||
<img id="lightbox-img" src="" alt="">
|
<img id="lightbox-img" src="" alt="">
|
||||||
<p class="lightbox-caption" id="lightbox-caption"></p>
|
<p class="lightbox-caption" id="lightbox-caption"></p>
|
||||||
|
<div class="lightbox-actions">
|
||||||
|
<a class="lightbox-download" id="lightbox-download" href="#" download>
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||||
|
Скачать QR
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<p class="lightbox-hint">Клик вне QR или Esc — закрыть</p>
|
<p class="lightbox-hint">Клик вне QR или Esc — закрыть</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -423,11 +458,15 @@
|
|||||||
var img = document.getElementById('lightbox-img');
|
var img = document.getElementById('lightbox-img');
|
||||||
var caption = document.getElementById('lightbox-caption');
|
var caption = document.getElementById('lightbox-caption');
|
||||||
var closeBtn = document.getElementById('lightbox-close');
|
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.src = src;
|
||||||
img.alt = alt || text || 'QR';
|
img.alt = alt || text || 'QR';
|
||||||
caption.textContent = text || '';
|
caption.textContent = text || '';
|
||||||
|
downloadBtn.href = src;
|
||||||
|
downloadBtn.setAttribute('download', filename || 'qr.png');
|
||||||
|
downloadBtn.setAttribute('aria-label', 'Скачать ' + (filename || 'qr.png'));
|
||||||
box.classList.add('open');
|
box.classList.add('open');
|
||||||
box.setAttribute('aria-hidden', 'false');
|
box.setAttribute('aria-hidden', 'false');
|
||||||
document.body.classList.add('lightbox-open');
|
document.body.classList.add('lightbox-open');
|
||||||
@@ -439,11 +478,17 @@
|
|||||||
box.setAttribute('aria-hidden', 'true');
|
box.setAttribute('aria-hidden', 'true');
|
||||||
document.body.classList.remove('lightbox-open');
|
document.body.classList.remove('lightbox-open');
|
||||||
img.removeAttribute('src');
|
img.removeAttribute('src');
|
||||||
|
downloadBtn.removeAttribute('href');
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll('[data-lightbox-src]').forEach(function (el) {
|
document.querySelectorAll('[data-lightbox-src]').forEach(function (el) {
|
||||||
function openFromEl() {
|
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('click', openFromEl);
|
||||||
el.addEventListener('keydown', function (e) {
|
el.addEventListener('keydown', function (e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user