Add lightbox navigation arrows and author metadata display
This commit is contained in:
1 parent
d48f5227c3
commit
fdc5f4c94f
13 files changed
+112
-24
No files matched your search
@@ -1391,6 +1391,33 @@ footer.footer-modern a:hover {
|
|||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lightbox-arrow {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 2001;
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
color: #ffffff;
|
||||||
|
border: none;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 2rem;
|
||||||
|
line-height: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox-arrow:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox-prev { left: 20px; }
|
||||||
|
.lightbox-next { right: 20px; }
|
||||||
|
|
||||||
/* Zoomable image wrapper — JS wraps each content image in this span */
|
/* Zoomable image wrapper — JS wraps each content image in this span */
|
||||||
.zoomable-wrap {
|
.zoomable-wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -520,7 +520,7 @@
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Lightbox: click any article image to zoom -->
|
<!-- Lightbox: click any article image to zoom; carousel-aware prev/next -->
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var content = document.querySelector('.content');
|
var content = document.querySelector('.content');
|
||||||
@@ -529,16 +529,52 @@
|
|||||||
var images = content.querySelectorAll('img');
|
var images = content.querySelectorAll('img');
|
||||||
if (!images.length) return;
|
if (!images.length) return;
|
||||||
|
|
||||||
// Build overlay once, reuse for every image
|
// Build overlay with optional prev/next arrows for carousel galleries
|
||||||
var overlay = document.createElement('div');
|
var overlay = document.createElement('div');
|
||||||
overlay.className = 'lightbox-overlay';
|
overlay.className = 'lightbox-overlay';
|
||||||
|
|
||||||
|
var prevBtn = document.createElement('button');
|
||||||
|
prevBtn.type = 'button';
|
||||||
|
prevBtn.className = 'lightbox-arrow lightbox-prev';
|
||||||
|
prevBtn.innerHTML = '‹';
|
||||||
|
|
||||||
var zoomed = document.createElement('img');
|
var zoomed = document.createElement('img');
|
||||||
|
|
||||||
|
var nextBtn = document.createElement('button');
|
||||||
|
nextBtn.type = 'button';
|
||||||
|
nextBtn.className = 'lightbox-arrow lightbox-next';
|
||||||
|
nextBtn.innerHTML = '›';
|
||||||
|
|
||||||
|
overlay.appendChild(prevBtn);
|
||||||
overlay.appendChild(zoomed);
|
overlay.appendChild(zoomed);
|
||||||
|
overlay.appendChild(nextBtn);
|
||||||
document.body.appendChild(overlay);
|
document.body.appendChild(overlay);
|
||||||
|
|
||||||
function open(src, alt) {
|
var gallery = []; // images in the current carousel (empty = single image)
|
||||||
zoomed.src = src;
|
var galIdx = 0;
|
||||||
zoomed.alt = alt || '';
|
|
||||||
|
function showAt(idx) {
|
||||||
|
galIdx = (idx + gallery.length) % gallery.length;
|
||||||
|
zoomed.src = gallery[galIdx].src;
|
||||||
|
zoomed.alt = gallery[galIdx].alt || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(el) {
|
||||||
|
// If the image lives inside a carousel, collect all slides for navigation
|
||||||
|
var car = el.closest ? el.closest('.carousel') : null;
|
||||||
|
if (car) {
|
||||||
|
gallery = Array.prototype.slice.call(car.querySelectorAll('.carousel-slide img'));
|
||||||
|
galIdx = gallery.indexOf(el);
|
||||||
|
if (galIdx === -1) galIdx = 0;
|
||||||
|
} else {
|
||||||
|
gallery = [el];
|
||||||
|
galIdx = 0;
|
||||||
|
}
|
||||||
|
var hasMultiple = gallery.length > 1;
|
||||||
|
prevBtn.style.display = hasMultiple ? '' : 'none';
|
||||||
|
nextBtn.style.display = hasMultiple ? '' : 'none';
|
||||||
|
zoomed.src = el.src;
|
||||||
|
zoomed.alt = el.alt || '';
|
||||||
overlay.classList.add('is-open');
|
overlay.classList.add('is-open');
|
||||||
document.body.style.overflow = 'hidden';
|
document.body.style.overflow = 'hidden';
|
||||||
}
|
}
|
||||||
@@ -548,20 +584,26 @@
|
|||||||
document.body.style.overflow = '';
|
document.body.style.overflow = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevBtn.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
showAt(galIdx - 1);
|
||||||
|
});
|
||||||
|
nextBtn.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
showAt(galIdx + 1);
|
||||||
|
});
|
||||||
|
|
||||||
function wrapImage(el) {
|
function wrapImage(el) {
|
||||||
// Skip icons / tiny images using natural dimensions (reliable after load)
|
|
||||||
if (el.naturalWidth > 0 && el.naturalWidth < 100) return;
|
if (el.naturalWidth > 0 && el.naturalWidth < 100) return;
|
||||||
if (el.naturalHeight > 0 && el.naturalHeight < 100) return;
|
if (el.naturalHeight > 0 && el.naturalHeight < 100) return;
|
||||||
|
|
||||||
var wrap = document.createElement('span');
|
var wrap = document.createElement('span');
|
||||||
wrap.className = 'zoomable-wrap';
|
wrap.className = 'zoomable-wrap';
|
||||||
el.parentNode.insertBefore(wrap, el);
|
el.parentNode.insertBefore(wrap, el);
|
||||||
wrap.appendChild(el);
|
wrap.appendChild(el);
|
||||||
el.addEventListener('click', function () { open(el.src, el.alt); });
|
el.addEventListener('click', function () { open(el); });
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.prototype.forEach.call(images, function (el) {
|
Array.prototype.forEach.call(images, function (el) {
|
||||||
// If already loaded (e.g. from cache) act immediately; otherwise wait
|
|
||||||
if (el.complete && el.naturalWidth) {
|
if (el.complete && el.naturalWidth) {
|
||||||
wrapImage(el);
|
wrapImage(el);
|
||||||
} else {
|
} else {
|
||||||
@@ -569,12 +611,16 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
overlay.addEventListener('click', close);
|
// Close on backdrop click (not on arrows or image)
|
||||||
|
overlay.addEventListener('click', function (e) {
|
||||||
|
if (e.target === overlay) close();
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('keydown', function (e) {
|
document.addEventListener('keydown', function (e) {
|
||||||
if ((e.key === 'Escape' || e.key === 'Esc') && overlay.classList.contains('is-open')) {
|
if (!overlay.classList.contains('is-open')) return;
|
||||||
close();
|
if (e.key === 'Escape' || e.key === 'Esc') close();
|
||||||
}
|
if (e.key === 'ArrowLeft' && gallery.length > 1) showAt(galIdx - 1);
|
||||||
|
if (e.key === 'ArrowRight' && gallery.length > 1) showAt(galIdx + 1);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Ein Bludit-Theme, inspiriert vom Blowfish-Hugo-Theme. Rechte Seitenleiste, Lesezeit, Umschalter für hellen/dunklen Modus und eine Navigationsleiste mit Social-Media-Icons und statischen Seiten."
|
"description": "Ein Bludit-Theme, inspiriert vom Blowfish-Hugo-Theme. Rechte Seitenleiste, Lesezeit, Umschalter für hellen/dunklen Modus und eine Navigationsleiste mit Social-Media-Icons und statischen Seiten."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Design wechseln"
|
"Toggle theme": "Design wechseln",
|
||||||
|
"Author": "Autor"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Ein Bludit-Theme, inspiriert vom Blowfish-Hugo-Theme. Rechte Seitenleiste, Lesezeit, Umschalter für hellen/dunklen Modus und eine Navigationsleiste mit Social-Media-Icons und statischen Seiten."
|
"description": "Ein Bludit-Theme, inspiriert vom Blowfish-Hugo-Theme. Rechte Seitenleiste, Lesezeit, Umschalter für hellen/dunklen Modus und eine Navigationsleiste mit Social-Media-Icons und statischen Seiten."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Design wechseln"
|
"Toggle theme": "Design wechseln",
|
||||||
|
"Author": "Autor"
|
||||||
}
|
}
|
||||||
+2
-1
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "A Bludit theme inspired by the Blowfish Hugo theme. Right sidebar, reading time, a light/dark mode toggle and a navbar with social icons and static pages."
|
"description": "A Bludit theme inspired by the Blowfish Hugo theme. Right sidebar, reading time, a light/dark mode toggle and a navbar with social icons and static pages."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Toggle theme"
|
"Toggle theme": "Toggle theme",
|
||||||
|
"Author": "Author"
|
||||||
}
|
}
|
||||||
+2
-1
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Un tema para Bludit inspirado en el tema Blowfish de Hugo. Barra lateral derecha, tiempo de lectura, conmutador de modo claro/oscuro y barra de navegación con iconos sociales y páginas estáticas."
|
"description": "Un tema para Bludit inspirado en el tema Blowfish de Hugo. Barra lateral derecha, tiempo de lectura, conmutador de modo claro/oscuro y barra de navegación con iconos sociales y páginas estáticas."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Cambiar tema"
|
"Toggle theme": "Cambiar tema",
|
||||||
|
"Author": "Autor"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "یک قالب بلودیت با الهام از قالب Blowfish هوگو. نوار کناری راست، زمان مطالعه، کلید تغییر حالت روشن/تاریک و نوار ناوبری به همراه آیکونهای شبکههای اجتماعی و صفحات ایستا."
|
"description": "یک قالب بلودیت با الهام از قالب Blowfish هوگو. نوار کناری راست، زمان مطالعه، کلید تغییر حالت روشن/تاریک و نوار ناوبری به همراه آیکونهای شبکههای اجتماعی و صفحات ایستا."
|
||||||
},
|
},
|
||||||
"Toggle theme": "تغییر پوسته"
|
"Toggle theme": "تغییر پوسته",
|
||||||
|
"Author": "نویسنده"
|
||||||
}
|
}
|
||||||
+2
-1
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Un tema per Bludit ispirato al tema Blowfish di Hugo. Barra laterale a destra, tempo di lettura, interruttore per la modalità chiara/scura e barra di navigazione con icone social e pagine statiche."
|
"description": "Un tema per Bludit ispirato al tema Blowfish di Hugo. Barra laterale a destra, tempo di lettura, interruttore per la modalità chiara/scura e barra di navigazione con icone social e pagine statiche."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Cambia tema"
|
"Toggle theme": "Cambia tema",
|
||||||
|
"Author": "Autore"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Hugo の Blowfish テーマにインスパイアされた Bludit テーマ。右サイドバー、読了時間、ライト/ダークモードの切り替え、ソーシャルアイコンと固定ページを備えたナビゲーションバーを搭載しています。"
|
"description": "Hugo の Blowfish テーマにインスパイアされた Bludit テーマ。右サイドバー、読了時間、ライト/ダークモードの切り替え、ソーシャルアイコンと固定ページを備えたナビゲーションバーを搭載しています。"
|
||||||
},
|
},
|
||||||
"Toggle theme": "テーマを切り替え"
|
"Toggle theme": "テーマを切り替え",
|
||||||
|
"Author": "著者"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Een Bludit-thema geïnspireerd op het Blowfish-thema voor Hugo. Zijbalk rechts, leestijd, schakelaar voor lichte/donkere modus en een navigatiebalk met sociale iconen en statische pagina's."
|
"description": "Een Bludit-thema geïnspireerd op het Blowfish-thema voor Hugo. Zijbalk rechts, leestijd, schakelaar voor lichte/donkere modus en een navigatiebalk met sociale iconen en statische pagina's."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Thema wisselen"
|
"Toggle theme": "Thema wisselen",
|
||||||
|
"Author": "Auteur"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Тема для Bludit, вдохновлённая темой Blowfish для Hugo. Боковая панель справа, время чтения, переключатель светлой/тёмной темы и панель навигации со значками соцсетей и статическими страницами."
|
"description": "Тема для Bludit, вдохновлённая темой Blowfish для Hugo. Боковая панель справа, время чтения, переключатель светлой/тёмной темы и панель навигации со значками соцсетей и статическими страницами."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Переключить тему"
|
"Toggle theme": "Переключить тему",
|
||||||
|
"Author": "Автор"
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"name": "Blowdit",
|
"name": "Blowdit",
|
||||||
"description": "Hugo'nun Blowfish temasından esinlenen bir Bludit teması. Sağ kenar çubuğu, okuma süresi, açık/koyu mod düğmesi ve sosyal simgeler ile sabit sayfalar içeren bir gezinme çubuğu."
|
"description": "Hugo'nun Blowfish temasından esinlenen bir Bludit teması. Sağ kenar çubuğu, okuma süresi, açık/koyu mod düğmesi ve sosyal simgeler ile sabit sayfalar içeren bir gezinme çubuğu."
|
||||||
},
|
},
|
||||||
"Toggle theme": "Temayı değiştir"
|
"Toggle theme": "Temayı değiştir",
|
||||||
|
"Author": "Yazar"
|
||||||
}
|
}
|
||||||
+6
-1
@@ -16,10 +16,15 @@
|
|||||||
<h1 class="title"><?php echo $page->title(); ?></h1>
|
<h1 class="title"><?php echo $page->title(); ?></h1>
|
||||||
|
|
||||||
<?php if (!$page->isStatic() && !$url->notFound()): ?>
|
<?php if (!$page->isStatic() && !$url->notFound()): ?>
|
||||||
<!-- Creation date and reading time -->
|
<!-- Creation date, reading time and author -->
|
||||||
|
<?php
|
||||||
|
$_authorUser = $users->getUser($page->username());
|
||||||
|
$_authorName = ($_authorUser && $_authorUser->nickname()) ? $_authorUser->nickname() : $page->username();
|
||||||
|
?>
|
||||||
<div class="metadata mb-4">
|
<div class="metadata mb-4">
|
||||||
<span><i class="bi bi-calendar3"></i><?php echo $page->date(); ?></span>
|
<span><i class="bi bi-calendar3"></i><?php echo $page->date(); ?></span>
|
||||||
<span><i class="bi bi-clock-history"></i><?php echo $L->get('Reading time') . ': ' . $page->readingTime() ?></span>
|
<span><i class="bi bi-clock-history"></i><?php echo $L->get('Reading time') . ': ' . $page->readingTime() ?></span>
|
||||||
|
<span><i class="bi bi-person"></i><?php echo $L->get('Author') . ': ' . htmlspecialchars($_authorName) ?></span>
|
||||||
</div>
|
</div>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user