Beta-2.1 - The clearer, the faster #22
@ -1,19 +1,14 @@
|
|||||||
// --- Arrays to store gallery and hero images ---
|
|
||||||
let galleryImages = [];
|
let galleryImages = [];
|
||||||
let heroImages = [];
|
let heroImages = [];
|
||||||
let allTags = []; // global tag list
|
let allTags = [];
|
||||||
let showOnlyUntagged = false;
|
let showOnlyUntagged = false;
|
||||||
|
|
||||||
// --- Fade-in helper ---
|
// --- Fade-in helper ---
|
||||||
function applyFadeInImages(container) {
|
function applyFadeInImages(container) {
|
||||||
const fadeImages = container.querySelectorAll("img.fade-in-img");
|
container.querySelectorAll("img.fade-in-img").forEach(img => {
|
||||||
fadeImages.forEach(img => {
|
const onLoad = () => img.classList.add("loaded");
|
||||||
const onLoad = () => {
|
if (img.complete && img.naturalHeight !== 0) onLoad();
|
||||||
img.classList.add("loaded");
|
else {
|
||||||
};
|
|
||||||
if (img.complete && img.naturalHeight !== 0) {
|
|
||||||
onLoad();
|
|
||||||
} else {
|
|
||||||
img.addEventListener("load", onLoad, { once: true });
|
img.addEventListener("load", onLoad, { once: true });
|
||||||
img.addEventListener("error", () => {
|
img.addEventListener("error", () => {
|
||||||
console.warn("Image failed to load:", img.dataset?.src || img.src);
|
console.warn("Image failed to load:", img.dataset?.src || img.src);
|
||||||
@ -25,13 +20,10 @@ function applyFadeInImages(container) {
|
|||||||
// --- Load images from server on page load ---
|
// --- Load images from server on page load ---
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
try {
|
try {
|
||||||
const galleryRes = await fetch('/api/gallery');
|
galleryImages = await (await fetch('/api/gallery')).json();
|
||||||
galleryImages = await galleryRes.json();
|
|
||||||
updateAllTags();
|
updateAllTags();
|
||||||
renderGallery();
|
renderGallery();
|
||||||
|
heroImages = await (await fetch('/api/hero')).json();
|
||||||
const heroRes = await fetch('/api/hero');
|
|
||||||
heroImages = await heroRes.json();
|
|
||||||
renderHero();
|
renderHero();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@ -43,31 +35,44 @@ async function loadData() {
|
|||||||
function updateAllTags() {
|
function updateAllTags() {
|
||||||
allTags = [];
|
allTags = [];
|
||||||
galleryImages.forEach(img => {
|
galleryImages.forEach(img => {
|
||||||
if (img.tags) img.tags.forEach(t => {
|
(img.tags || []).forEach(t => {
|
||||||
if (!allTags.includes(t)) allTags.push(t);
|
if (!allTags.includes(t)) allTags.push(t);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Helper: update count and button visibility ---
|
||||||
|
function updateCountAndButtons(prefix, count) {
|
||||||
|
const countTop = document.getElementById(`${prefix}-count`);
|
||||||
|
const countBottom = document.getElementById(`${prefix}-count-bottom`);
|
||||||
|
if (countTop) countTop.innerHTML = `<p>${count} photos</p>`;
|
||||||
|
if (countBottom) countBottom.innerHTML = `<p>${count} photos</p>`;
|
||||||
|
|
||||||
|
const removeAllBtn = document.getElementById(`remove-all-${prefix}`);
|
||||||
|
const removeAllBtnBottom = document.getElementById(`remove-all-${prefix}-bottom`);
|
||||||
|
if (removeAllBtn) removeAllBtn.style.display = count > 0 ? 'inline-block' : 'none';
|
||||||
|
if (removeAllBtnBottom) removeAllBtnBottom.style.display = count > 0 ? 'inline-block' : 'none';
|
||||||
|
|
||||||
|
const bottomUpload = document.getElementById(`bottom-${prefix}-upload`);
|
||||||
|
if (bottomUpload) bottomUpload.style.display = count > 0 ? 'flex' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
// --- Render gallery images with tags and delete buttons ---
|
// --- Render gallery images with tags and delete buttons ---
|
||||||
function renderGallery() {
|
function renderGallery() {
|
||||||
const container = document.getElementById('gallery');
|
const container = document.getElementById('gallery');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
let imagesToShow = showOnlyUntagged
|
||||||
// Filter images if toggle is on
|
? galleryImages.filter(img => !img.tags || img.tags.length === 0)
|
||||||
let imagesToShow = galleryImages;
|
: galleryImages;
|
||||||
if (showOnlyUntagged) {
|
|
||||||
imagesToShow = galleryImages.filter(img => !img.tags || img.tags.length === 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagesToShow.forEach((img) => {
|
imagesToShow.forEach((img) => {
|
||||||
const i = galleryImages.indexOf(img); // Use real index for tag/delete actions
|
const i = galleryImages.indexOf(img);
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'photo flex-item flex-column';
|
div.className = 'photo flex-item flex-column';
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="flex-item">
|
<div class="flex-item">
|
||||||
<img class="fade-in-img" src="/photos/${img.src}">
|
<img class="fade-in-img" src="/photos/${img.src}">
|
||||||
</div>
|
</div>
|
||||||
<div class="tags-display" data-index="${i}"></div>
|
<div class="tags-display" data-index="${i}"></div>
|
||||||
<div class="flex-item flex-full">
|
<div class="flex-item flex-full">
|
||||||
<div class="flex-item flex-end">
|
<div class="flex-item flex-end">
|
||||||
@ -77,41 +82,10 @@ function renderGallery() {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
container.appendChild(div);
|
container.appendChild(div);
|
||||||
|
|
||||||
renderTags(i, img.tags || []);
|
renderTags(i, img.tags || []);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update gallery count (top)
|
updateCountAndButtons('gallery', imagesToShow.length);
|
||||||
const galleryCount = document.getElementById('gallery-count');
|
|
||||||
if (galleryCount) {
|
|
||||||
galleryCount.innerHTML = `<p>${imagesToShow.length} photos</p>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update gallery count (bottom)
|
|
||||||
const galleryCountBottom = document.getElementById('gallery-count-bottom');
|
|
||||||
if (galleryCountBottom) {
|
|
||||||
galleryCountBottom.innerHTML = `<p>${imagesToShow.length} photos</p>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide Remove All button (top)
|
|
||||||
const removeAllBtn = document.getElementById('remove-all-gallery');
|
|
||||||
if (removeAllBtn) {
|
|
||||||
removeAllBtn.style.display = imagesToShow.length > 0 ? 'inline-block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide bottom upload row
|
|
||||||
const bottomGalleryUpload = document.getElementById('bottom-gallery-upload');
|
|
||||||
if (bottomGalleryUpload) {
|
|
||||||
bottomGalleryUpload.style.display = imagesToShow.length > 0 ? 'flex' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide Remove All button (bottom)
|
|
||||||
const removeAllBtnBottom = document.getElementById('remove-all-gallery-bottom');
|
|
||||||
if (removeAllBtnBottom) {
|
|
||||||
removeAllBtnBottom.style.display = imagesToShow.length > 0 ? 'inline-block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fade-in effect for loaded images
|
|
||||||
applyFadeInImages(container);
|
applyFadeInImages(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +93,6 @@ function renderGallery() {
|
|||||||
function renderTags(imgIndex, tags) {
|
function renderTags(imgIndex, tags) {
|
||||||
const tagsDisplay = document.querySelector(`.tags-display[data-index="${imgIndex}"]`);
|
const tagsDisplay = document.querySelector(`.tags-display[data-index="${imgIndex}"]`);
|
||||||
const inputContainer = document.querySelector(`.tag-input[data-index="${imgIndex}"]`);
|
const inputContainer = document.querySelector(`.tag-input[data-index="${imgIndex}"]`);
|
||||||
|
|
||||||
tagsDisplay.innerHTML = '';
|
tagsDisplay.innerHTML = '';
|
||||||
inputContainer.innerHTML = '';
|
inputContainer.innerHTML = '';
|
||||||
|
|
||||||
@ -127,7 +100,6 @@ function renderTags(imgIndex, tags) {
|
|||||||
const span = document.createElement('span');
|
const span = document.createElement('span');
|
||||||
span.className = 'tag';
|
span.className = 'tag';
|
||||||
span.textContent = tag;
|
span.textContent = tag;
|
||||||
|
|
||||||
const remove = document.createElement('span');
|
const remove = document.createElement('span');
|
||||||
remove.className = 'remove-tag';
|
remove.className = 'remove-tag';
|
||||||
remove.textContent = '×';
|
remove.textContent = '×';
|
||||||
@ -136,7 +108,6 @@ function renderTags(imgIndex, tags) {
|
|||||||
updateTags(imgIndex, tags);
|
updateTags(imgIndex, tags);
|
||||||
renderTags(imgIndex, tags);
|
renderTags(imgIndex, tags);
|
||||||
};
|
};
|
||||||
|
|
||||||
span.appendChild(remove);
|
span.appendChild(remove);
|
||||||
tagsDisplay.appendChild(span);
|
tagsDisplay.appendChild(span);
|
||||||
});
|
});
|
||||||
@ -146,11 +117,10 @@ function renderTags(imgIndex, tags) {
|
|||||||
input.placeholder = 'Add tag...';
|
input.placeholder = 'Add tag...';
|
||||||
inputContainer.appendChild(input);
|
inputContainer.appendChild(input);
|
||||||
|
|
||||||
// --- Validate button ---
|
|
||||||
const validateBtn = document.createElement('button');
|
const validateBtn = document.createElement('button');
|
||||||
validateBtn.textContent = '✔️';
|
validateBtn.textContent = '✔️';
|
||||||
validateBtn.className = 'validate-tag-btn';
|
validateBtn.className = 'validate-tag-btn';
|
||||||
validateBtn.style.display = 'none'; // hidden by default
|
validateBtn.style.display = 'none';
|
||||||
validateBtn.style.marginLeft = '4px';
|
validateBtn.style.marginLeft = '4px';
|
||||||
inputContainer.appendChild(validateBtn);
|
inputContainer.appendChild(validateBtn);
|
||||||
|
|
||||||
@ -170,30 +140,20 @@ function renderTags(imgIndex, tags) {
|
|||||||
|
|
||||||
const updateSuggestions = () => {
|
const updateSuggestions = () => {
|
||||||
const value = input.value.toLowerCase();
|
const value = input.value.toLowerCase();
|
||||||
|
|
||||||
const allTagsFlat = galleryImages.flatMap(img => img.tags || []);
|
const allTagsFlat = galleryImages.flatMap(img => img.tags || []);
|
||||||
const tagCount = {};
|
const tagCount = {};
|
||||||
allTagsFlat.forEach(t => tagCount[t] = (tagCount[t] || 0) + 1);
|
allTagsFlat.forEach(t => tagCount[t] = (tagCount[t] || 0) + 1);
|
||||||
|
const allTagsSorted = Object.keys(tagCount).sort((a, b) => tagCount[b] - tagCount[a]);
|
||||||
const allTagsSorted = Object.keys(tagCount)
|
|
||||||
.sort((a, b) => tagCount[b] - tagCount[a]);
|
|
||||||
|
|
||||||
const suggestions = allTagsSorted.filter(t => t.toLowerCase().startsWith(value) && !tags.includes(t));
|
const suggestions = allTagsSorted.filter(t => t.toLowerCase().startsWith(value) && !tags.includes(t));
|
||||||
|
|
||||||
suggestionBox.innerHTML = '';
|
suggestionBox.innerHTML = '';
|
||||||
selectedIndex = -1;
|
selectedIndex = -1;
|
||||||
|
|
||||||
if (suggestions.length) {
|
if (suggestions.length) {
|
||||||
suggestionBox.style.display = 'block';
|
suggestionBox.style.display = 'block';
|
||||||
suggestions.forEach((s, idx) => {
|
suggestions.forEach((s, idx) => {
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.style.fontStyle = 'italic';
|
li.style.fontStyle = 'italic';
|
||||||
li.style.textAlign = 'left';
|
li.style.textAlign = 'left';
|
||||||
|
li.innerHTML = `<b>${s.substring(0, input.value.length)}</b>${s.substring(input.value.length)}`;
|
||||||
const boldPart = `<b>${s.substring(0, input.value.length)}</b>`;
|
|
||||||
const rest = s.substring(input.value.length);
|
|
||||||
li.innerHTML = boldPart + rest;
|
|
||||||
|
|
||||||
li.addEventListener('mousedown', (e) => {
|
li.addEventListener('mousedown', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
addTag(s);
|
addTag(s);
|
||||||
@ -201,7 +161,6 @@ function renderTags(imgIndex, tags) {
|
|||||||
input.focus();
|
input.focus();
|
||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
});
|
});
|
||||||
|
|
||||||
li.onmouseover = () => selectedIndex = idx;
|
li.onmouseover = () => selectedIndex = idx;
|
||||||
suggestionBox.appendChild(li);
|
suggestionBox.appendChild(li);
|
||||||
});
|
});
|
||||||
@ -218,7 +177,6 @@ function renderTags(imgIndex, tags) {
|
|||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
validateBtn.style.display = input.value.trim() ? 'inline-block' : 'none';
|
validateBtn.style.display = input.value.trim() ? 'inline-block' : 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
input.addEventListener('keydown', (e) => {
|
input.addEventListener('keydown', (e) => {
|
||||||
const items = suggestionBox.querySelectorAll('li');
|
const items = suggestionBox.querySelectorAll('li');
|
||||||
if (e.key === 'ArrowDown') {
|
if (e.key === 'ArrowDown') {
|
||||||
@ -249,26 +207,22 @@ function renderTags(imgIndex, tags) {
|
|||||||
validateBtn.style.display = 'none';
|
validateBtn.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
input.addEventListener('blur', () => {
|
input.addEventListener('blur', () => {
|
||||||
suggestionBox.style.display = 'none';
|
suggestionBox.style.display = 'none';
|
||||||
input.value = '';
|
input.value = '';
|
||||||
validateBtn.style.display = 'none';
|
validateBtn.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
validateBtn.addEventListener('mousedown', (e) => {
|
||||||
// --- Validate button action ---
|
e.preventDefault();
|
||||||
validateBtn.onclick = () => {
|
|
||||||
if (input.value.trim()) {
|
if (input.value.trim()) {
|
||||||
addTag(input.value.trim());
|
addTag(input.value.trim());
|
||||||
input.value = '';
|
input.value = '';
|
||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
validateBtn.style.display = 'none';
|
validateBtn.style.display = 'none';
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
if (!input.value.trim()) {
|
if (!input.value.trim()) suggestionBox.style.display = 'none';
|
||||||
suggestionBox.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Update tags in galleryImages array ---
|
// --- Update tags in galleryImages array ---
|
||||||
@ -296,38 +250,7 @@ function renderHero() {
|
|||||||
`;
|
`;
|
||||||
container.appendChild(div);
|
container.appendChild(div);
|
||||||
});
|
});
|
||||||
|
updateCountAndButtons('hero', heroImages.length);
|
||||||
// Update hero count (top)
|
|
||||||
const heroCount = document.getElementById('hero-count');
|
|
||||||
if (heroCount) {
|
|
||||||
heroCount.innerHTML = `<p>${heroImages.length} photos</p>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update hero count (bottom)
|
|
||||||
const heroCountBottom = document.getElementById('hero-count-bottom');
|
|
||||||
if (heroCountBottom) {
|
|
||||||
heroCountBottom.innerHTML = `<p>${heroImages.length} photos</p>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide Remove All button (top)
|
|
||||||
const removeAllBtn = document.getElementById('remove-all-hero');
|
|
||||||
if (removeAllBtn) {
|
|
||||||
removeAllBtn.style.display = heroImages.length > 0 ? 'inline-block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide bottom upload row
|
|
||||||
const bottomHeroUpload = document.getElementById('bottom-hero-upload');
|
|
||||||
if (bottomHeroUpload) {
|
|
||||||
bottomHeroUpload.style.display = heroImages.length > 0 ? 'flex' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show/hide Remove All button (bottom)
|
|
||||||
const removeAllBtnBottom = document.getElementById('remove-all-hero-bottom');
|
|
||||||
if (removeAllBtnBottom) {
|
|
||||||
removeAllBtnBottom.style.display = heroImages.length > 0 ? 'inline-block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fade-in effect for loaded images
|
|
||||||
applyFadeInImages(container);
|
applyFadeInImages(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,33 +297,27 @@ async function refreshHero() {
|
|||||||
function showToast(message, type = "success", duration = 3000) {
|
function showToast(message, type = "success", duration = 3000) {
|
||||||
const container = document.getElementById("toast-container");
|
const container = document.getElementById("toast-container");
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
const toast = document.createElement("div");
|
const toast = document.createElement("div");
|
||||||
toast.className = `toast ${type}`;
|
toast.className = `toast ${type}`;
|
||||||
toast.textContent = message;
|
toast.textContent = message;
|
||||||
container.appendChild(toast);
|
container.appendChild(toast);
|
||||||
|
|
||||||
requestAnimationFrame(() => toast.classList.add("show"));
|
requestAnimationFrame(() => toast.classList.add("show"));
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toast.classList.remove("show");
|
toast.classList.remove("show");
|
||||||
toast.addEventListener("transitionend", () => toast.remove());
|
toast.addEventListener("transitionend", () => toast.remove());
|
||||||
}, duration);
|
}, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pendingDelete = null; // { type: 'gallery'|'hero'|'gallery-all'|'hero-all', index: number|null }
|
let pendingDelete = null;
|
||||||
|
|
||||||
// --- Show delete confirmation modal ---
|
// --- Show delete confirmation modal ---
|
||||||
function showDeleteModal(type, index = null) {
|
function showDeleteModal(type, index = null) {
|
||||||
pendingDelete = { type, index };
|
pendingDelete = { type, index };
|
||||||
const modalText = document.getElementById('delete-modal-text');
|
const modalText = document.getElementById('delete-modal-text');
|
||||||
if (type === 'gallery-all') {
|
modalText.textContent =
|
||||||
modalText.textContent = "Are you sure you want to delete ALL gallery images?";
|
type === 'gallery-all' ? "Are you sure you want to delete ALL gallery images?"
|
||||||
} else if (type === 'hero-all') {
|
: type === 'hero-all' ? "Are you sure you want to delete ALL hero images?"
|
||||||
modalText.textContent = "Are you sure you want to delete ALL hero images?";
|
: "Are you sure you want to delete this image?";
|
||||||
} else {
|
|
||||||
modalText.textContent = "Are you sure you want to delete this image?";
|
|
||||||
}
|
|
||||||
document.getElementById('delete-modal').style.display = 'flex';
|
document.getElementById('delete-modal').style.display = 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,15 +330,10 @@ function hideDeleteModal() {
|
|||||||
// --- Confirm deletion ---
|
// --- Confirm deletion ---
|
||||||
async function confirmDelete() {
|
async function confirmDelete() {
|
||||||
if (!pendingDelete) return;
|
if (!pendingDelete) return;
|
||||||
if (pendingDelete.type === 'gallery') {
|
if (pendingDelete.type === 'gallery') await actuallyDeleteGalleryImage(pendingDelete.index);
|
||||||
await actuallyDeleteGalleryImage(pendingDelete.index);
|
else if (pendingDelete.type === 'hero') await actuallyDeleteHeroImage(pendingDelete.index);
|
||||||
} else if (pendingDelete.type === 'hero') {
|
else if (pendingDelete.type === 'gallery-all') await actuallyDeleteAllGalleryImages();
|
||||||
await actuallyDeleteHeroImage(pendingDelete.index);
|
else if (pendingDelete.type === 'hero-all') await actuallyDeleteAllHeroImages();
|
||||||
} else if (pendingDelete.type === 'gallery-all') {
|
|
||||||
await actuallyDeleteAllGalleryImages();
|
|
||||||
} else if (pendingDelete.type === 'hero-all') {
|
|
||||||
await actuallyDeleteAllHeroImages();
|
|
||||||
}
|
|
||||||
hideDeleteModal();
|
hideDeleteModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,41 +415,36 @@ async function actuallyDeleteAllHeroImages() {
|
|||||||
|
|
||||||
// --- Modal event listeners and bulk delete buttons ---
|
// --- Modal event listeners and bulk delete buttons ---
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
document.getElementById('delete-modal-close').onclick = hideDeleteModal;
|
['delete-modal-close', 'delete-modal-cancel'].forEach(id => {
|
||||||
document.getElementById('delete-modal-cancel').onclick = hideDeleteModal;
|
const el = document.getElementById(id);
|
||||||
document.getElementById('delete-modal-confirm').onclick = confirmDelete;
|
if (el) el.onclick = hideDeleteModal;
|
||||||
|
});
|
||||||
|
const confirmBtn = document.getElementById('delete-modal-confirm');
|
||||||
|
if (confirmBtn) confirmBtn.onclick = confirmDelete;
|
||||||
|
|
||||||
// --- Radio toggle for gallery filter ---
|
// Gallery filter radios
|
||||||
const showAllRadio = document.getElementById('show-all-radio');
|
const showAllRadio = document.getElementById('show-all-radio');
|
||||||
const showUntaggedRadio = document.getElementById('show-untagged-radio');
|
const showUntaggedRadio = document.getElementById('show-untagged-radio');
|
||||||
|
if (showAllRadio) showAllRadio.addEventListener('change', () => {
|
||||||
if (showAllRadio && showUntaggedRadio) {
|
showOnlyUntagged = false;
|
||||||
showAllRadio.addEventListener('change', () => {
|
renderGallery();
|
||||||
if (showAllRadio.checked) {
|
});
|
||||||
showOnlyUntagged = false;
|
if (showUntaggedRadio) showUntaggedRadio.addEventListener('change', () => {
|
||||||
renderGallery();
|
showOnlyUntagged = true;
|
||||||
}
|
renderGallery();
|
||||||
});
|
});
|
||||||
showUntaggedRadio.addEventListener('change', () => {
|
|
||||||
if (showUntaggedRadio.checked) {
|
|
||||||
showOnlyUntagged = true;
|
|
||||||
renderGallery();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bulk delete buttons
|
// Bulk delete buttons
|
||||||
const removeAllGalleryBtn = document.getElementById('remove-all-gallery');
|
[
|
||||||
const removeAllGalleryBtnBottom = document.getElementById('remove-all-gallery-bottom');
|
['remove-all-gallery', 'gallery-all'],
|
||||||
const removeAllHeroBtn = document.getElementById('remove-all-hero');
|
['remove-all-gallery-bottom', 'gallery-all'],
|
||||||
const removeAllHeroBtnBottom = document.getElementById('remove-all-hero-bottom');
|
['remove-all-hero', 'hero-all'],
|
||||||
if (removeAllGalleryBtn) removeAllGalleryBtn.onclick = () => showDeleteModal('gallery-all');
|
['remove-all-hero-bottom', 'hero-all']
|
||||||
if (removeAllGalleryBtnBottom) removeAllGalleryBtnBottom.onclick = () => showDeleteModal('gallery-all');
|
].forEach(([btnId, type]) => {
|
||||||
if (removeAllHeroBtn) removeAllHeroBtn.onclick = () => showDeleteModal('hero-all');
|
const btn = document.getElementById(btnId);
|
||||||
if (removeAllHeroBtnBottom) removeAllHeroBtnBottom.onclick = () => showDeleteModal('hero-all');
|
if (btn) btn.onclick = () => showDeleteModal(type);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// --- Initialize ---
|
// --- Initialize ---
|
||||||
loadData();
|
loadData();
|
Reference in New Issue
Block a user