| Server IP : 173.209.174.21 / Your IP : 216.73.216.89 Web Server : Apache/2.4.58 (Ubuntu) System : Linux wcfs-server 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 User : nodor ( 1000) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/grangestation/ |
Upload File : |
let galleryPhotos = activeGalleryPhotos();
let galleryConfig = getSiteConfig();
const galleryGrid = document.querySelector("[data-full-gallery-grid]");
const lightbox = document.querySelector("[data-lightbox]");
const lightboxImage = document.querySelector("[data-lightbox-image]");
const lightboxCaption = document.querySelector("[data-lightbox-caption]");
const galleryThumbs = document.querySelector("[data-gallery-thumbs]");
let currentPhoto = 0;
async function apiRequest(action) {
const response = await fetch(`api/index.php?action=${encodeURIComponent(action)}`);
const data = await response.json();
if (!response.ok || !data.ok) throw new Error(data.error || "Request failed.");
return data;
}
async function loadLiveGallery() {
try {
const data = await apiRequest("bootstrap");
galleryConfig = mergeConfig(data.settings || {});
galleryPhotos = (galleryConfig.gallery || []).filter((photo) => photo.enabled !== false);
} catch (error) {
galleryPhotos = activeGalleryPhotos();
}
}
function escapeHtml(value) {
return String(value ?? "")
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
function applyBrandingSettings() {
const branding = galleryConfig.branding || {};
const venueName = branding.venueName || "Grange Station";
const tagline = branding.tagline || "Wilson Creek, WA";
const logoImage = branding.logoImage || "";
const heroImage = branding.heroImage || "assets/grange-station.png";
const socialImage = branding.socialImage || heroImage;
document.querySelectorAll(".brand-mark").forEach((mark) => {
mark.innerHTML = logoImage ? `<img src="${escapeHtml(logoImage)}" alt="">` : "GS";
mark.classList.toggle("has-logo", Boolean(logoImage));
});
document.querySelectorAll(".site-header, .gallery-header").forEach((item) => {
item.classList.toggle("has-logo", Boolean(logoImage));
});
document.querySelectorAll(".brand strong").forEach((item) => item.textContent = venueName);
document.querySelectorAll(".brand small").forEach((item) => item.textContent = tagline);
const hero = document.querySelector(".gallery-hero > img");
if (hero) {
hero.src = heroImage;
hero.alt = `${venueName} venue exterior.`;
}
document.querySelectorAll("meta[property='og:image'], meta[name='twitter:image']").forEach((meta) => {
meta.setAttribute("content", socialImage.startsWith("http") ? socialImage : `https://www.grangestation.com/${socialImage}`);
});
}
function photoIndexFromUrl() {
const requested = Number(new URLSearchParams(window.location.search).get("photo"));
if (!Number.isInteger(requested)) return -1;
return requested >= 0 && requested < galleryPhotos.length ? requested : -1;
}
function renderGalleryGrid() {
const selected = photoIndexFromUrl();
galleryGrid.innerHTML = galleryPhotos.map((photo, index) => `
<button class="full-gallery-card${index === selected ? " selected" : ""}" type="button" data-gallery-photo="${index}" aria-label="Open ${photo.caption}">
<img src="${photo.src}" alt="${photo.caption}" loading="lazy">
</button>
`).join("");
if (selected >= 0) {
const highlighted = galleryGrid.querySelector(`[data-gallery-photo="${selected}"]`);
highlighted?.scrollIntoView({ block: "center", behavior: "auto" });
}
}
function renderGalleryThumbs() {
galleryThumbs.innerHTML = galleryPhotos.map((photo, index) => `
<button type="button" class="${index === currentPhoto ? "active" : ""}" data-gallery-thumb="${index}" aria-label="Open gallery photo ${index + 1}">
<img src="${photo.src}" alt="">
</button>
`).join("");
}
function openPhoto(index) {
if (!galleryPhotos.length) return;
currentPhoto = (index + galleryPhotos.length) % galleryPhotos.length;
lightboxImage.src = galleryPhotos[currentPhoto].src;
lightboxImage.alt = galleryPhotos[currentPhoto].caption;
lightboxCaption.textContent = galleryPhotos[currentPhoto].caption;
renderGalleryThumbs();
if (!lightbox.open) lightbox.showModal();
}
galleryGrid.addEventListener("click", (event) => {
const button = event.target.closest("[data-gallery-photo]");
if (button) openPhoto(Number(button.dataset.galleryPhoto));
});
galleryThumbs.addEventListener("click", (event) => {
const button = event.target.closest("[data-gallery-thumb]");
if (button) openPhoto(Number(button.dataset.galleryThumb));
});
document.querySelector("[data-close-gallery]").addEventListener("click", () => lightbox.close());
document.querySelector("[data-prev-photo]").addEventListener("click", () => openPhoto(currentPhoto - 1));
document.querySelector("[data-next-photo]").addEventListener("click", () => openPhoto(currentPhoto + 1));
lightbox.addEventListener("click", (event) => {
if (event.target === lightbox) lightbox.close();
});
document.addEventListener("keydown", (event) => {
if (!lightbox.open) return;
if (event.key === "ArrowLeft") openPhoto(currentPhoto - 1);
if (event.key === "ArrowRight") openPhoto(currentPhoto + 1);
});
loadLiveGallery().finally(() => {
applyBrandingSettings();
renderGalleryGrid();
});