Merge remote-tracking branch 'origin/development'
This commit is contained in:
commit
1ee9c788d8
@ -39,21 +39,30 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Close Button positioning */
|
||||
/* Close Button */
|
||||
#gallery-close {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
font-size: 24px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
cursor: pointer;
|
||||
z-index: 100;
|
||||
background: transparent;
|
||||
border: none;
|
||||
z-index: 120;
|
||||
font-size: 1.1rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#gallery-close:hover {
|
||||
background: rgba(40, 40, 40, 0.85);
|
||||
}
|
||||
|
||||
/* Loader for gallery */
|
||||
#loader-container {
|
||||
position: fixed;
|
||||
@ -94,11 +103,14 @@
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
|
||||
.gallery-prev { left: 20px; }
|
||||
.gallery-next { right: 20px; }
|
||||
|
||||
.gallery-nav.nav-hidden { opacity: 0; }
|
||||
|
||||
#gallery-info {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
@ -225,6 +237,8 @@
|
||||
cursor: pointer;
|
||||
z-index: 120;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1;
|
||||
padding: 0 0 0 2px; /* optical compensation for ▶ glyph whitespace */
|
||||
--autoplay-duration: 5s;
|
||||
--play-progress: 0deg;
|
||||
overflow: visible;
|
||||
|
||||
@ -7,6 +7,7 @@ let exifAbortController = null;
|
||||
let isGalleryLoading = false;
|
||||
let autoPlayTimer = null;
|
||||
let isAutoPlay = false;
|
||||
let navHideTimer = null;
|
||||
const AUTO_PLAY_INTERVAL_MS = 5000;
|
||||
let pendingAutoAdvance = false;
|
||||
|
||||
@ -197,12 +198,13 @@ function updateDownloadLink(relUrl) {
|
||||
if (!relUrl) {
|
||||
downloadBtn.removeAttribute('href');
|
||||
downloadBtn.removeAttribute('download');
|
||||
downloadBtn.removeAttribute('data-relurl');
|
||||
return;
|
||||
}
|
||||
const parts = relUrl.split('/');
|
||||
const filename = parts[parts.length - 1] || relUrl;
|
||||
downloadBtn.href = '/media/' + encodeGalleryPath(relUrl) + '?download=true';
|
||||
downloadBtn.setAttribute('download', filename);
|
||||
// Store relUrl for the click handler (which fetches a short-lived token)
|
||||
downloadBtn.dataset.relurl = relUrl;
|
||||
downloadBtn.removeAttribute('href');
|
||||
downloadBtn.removeAttribute('download');
|
||||
}
|
||||
|
||||
function updateNextButtonState() {
|
||||
@ -216,11 +218,20 @@ function updateNextButtonState() {
|
||||
nextButton.setAttribute('aria-label', atLastImage ? 'Close gallery' : 'Next image');
|
||||
}
|
||||
|
||||
function showGalleryNav() {
|
||||
clearTimeout(navHideTimer);
|
||||
document.querySelectorAll('.gallery-nav').forEach(btn => btn.classList.remove('nav-hidden'));
|
||||
navHideTimer = setTimeout(() => {
|
||||
document.querySelectorAll('.gallery-nav').forEach(btn => btn.classList.add('nav-hidden'));
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function openGalleryModal(relUrl) {
|
||||
document.body.style.overflow = 'hidden'; // Disable background scrolling.
|
||||
currentGalleryIndex = currentGalleryImages.indexOf(relUrl);
|
||||
showGalleryImage(relUrl);
|
||||
document.getElementById('gallery-modal').style.display = 'flex';
|
||||
showGalleryNav();
|
||||
}
|
||||
|
||||
function showGalleryImage(relUrl) {
|
||||
@ -334,6 +345,8 @@ function preloadNextImage() {
|
||||
}
|
||||
|
||||
function closeGalleryModal() {
|
||||
clearTimeout(navHideTimer);
|
||||
document.querySelectorAll('.gallery-nav').forEach(btn => btn.classList.remove('nav-hidden'));
|
||||
document.getElementById('gallery-modal').style.display = 'none';
|
||||
isGalleryLoading = false;
|
||||
setAutoPlay(false);
|
||||
@ -388,7 +401,10 @@ function initGallerySwipe() {
|
||||
let touchEndX = 0;
|
||||
const galleryModal = document.getElementById('gallery-modal');
|
||||
|
||||
galleryModal.addEventListener('mousemove', showGalleryNav, false);
|
||||
|
||||
galleryModal.addEventListener('touchstart', function(e) {
|
||||
showGalleryNav();
|
||||
// If more than one finger is on screen, ignore swipe tracking.
|
||||
if (e.touches.length > 1) {
|
||||
return;
|
||||
@ -434,7 +450,7 @@ function setAutoPlay(active) {
|
||||
const playButton = document.getElementById('gallery-play');
|
||||
isAutoPlay = active;
|
||||
if (playButton) {
|
||||
playButton.textContent = active ? '||' : '>';
|
||||
playButton.textContent = active ? '\u23F8' : '\u25B6';
|
||||
playButton.setAttribute('aria-pressed', active ? 'true' : 'false');
|
||||
playButton.classList.toggle('playing', active);
|
||||
}
|
||||
@ -598,8 +614,40 @@ function initGalleryControls() {
|
||||
|
||||
const downloadButton = document.getElementById('gallery-download');
|
||||
if (downloadButton) {
|
||||
downloadButton.addEventListener('click', function (e) {
|
||||
downloadButton.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const relUrl = downloadButton.dataset.relurl;
|
||||
if (!relUrl) return;
|
||||
|
||||
const encodedSubpath = relUrl
|
||||
.replace(/^\/+/, '')
|
||||
.split('/')
|
||||
.map(segment => encodeURIComponent(decodeURIComponent(segment)))
|
||||
.join('/');
|
||||
|
||||
// Fetch a short-lived download token (works in Telegram's internal browser)
|
||||
let tokenizedUrl;
|
||||
try {
|
||||
const resp = await fetch(`/create_dltoken/${encodedSubpath}`);
|
||||
if (!resp.ok) return;
|
||||
tokenizedUrl = (await resp.text()).trim();
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tokenizedUrl) return;
|
||||
|
||||
// Append download=true so the server returns the full-size original as attachment
|
||||
const sep = tokenizedUrl.includes('?') ? '&' : '?';
|
||||
const downloadUrl = new URL(tokenizedUrl + sep + 'download=true', window.location.href);
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl.toString();
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -204,13 +204,13 @@
|
||||
|
||||
<!-- Gallery Modal for Images -->
|
||||
<div id="gallery-modal" style="display: none;">
|
||||
<button id="gallery-close">x</button>
|
||||
<button id="gallery-close">✕</button>
|
||||
<button id="gallery-info" aria-expanded="false" aria-controls="gallery-exif">i</button>
|
||||
<a id="gallery-download" aria-label="Download original image" title="Download original">⇩</a>
|
||||
<img id="gallery-modal-content" src="">
|
||||
<button class="gallery-nav gallery-prev">‹</button>
|
||||
<button class="gallery-nav gallery-next">›</button>
|
||||
<button id="gallery-play" aria-pressed="false" aria-label="Start slideshow">></button>
|
||||
<button id="gallery-play" aria-pressed="false" aria-label="Start slideshow">▶</button>
|
||||
<div id="gallery-exif" aria-live="polite"></div>
|
||||
<div id="gallery-filename" aria-live="polite"></div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user