fix: Photo gallery methods definition error
PROBLEM: - Photo gallery button caused 'this.showPhotoGallery is not a function' error - Methods were defined inside class but after closing brace - JavaScript couldn't find the methods in correct scope SOLUTION: - Moved all photo gallery methods to proper prototype definitions - Fixed method scope and accessibility issues - Changed from class methods to TaskChallengeGame.prototype methods - Consistent with existing codebase pattern (like showAnnoyanceManagement) FIXED METHODS: showPhotoGallery - main entry point setupPhotoGalleryEventListeners - UI event binding loadPhotoGallery - data loading and display updatePhotoStats - statistics display renderPhotoGrid - photo grid rendering with filters/sorting createPhotoItem - individual photo item HTML generation formatSessionName - session type display formatting filterPhotos - photo filtering logic showPhotoDetail - photo detail modal closePhotoDetail - modal close functionality downloadCurrentPhoto - individual photo download deleteCurrentPhoto - photo deletion with confirmation downloadAllPhotos - batch download functionality clearAllPhotos - bulk deletion with confirmation showPhotoSettings - settings modal display closePhotoSettings - settings modal close savePhotoSettings - settings persistence Photo gallery should now work correctly without JavaScript errors!
This commit is contained in:
parent
96c846cf8b
commit
5861c07bab
514
src/core/game.js
514
src/core/game.js
|
|
@ -6131,265 +6131,265 @@ class MusicManager {
|
|||
// Set current selection
|
||||
trackSelector.value = this.currentTrackIndex;
|
||||
}
|
||||
|
||||
// Photo Gallery Management Methods
|
||||
showPhotoGallery() {
|
||||
this.showScreen('photo-gallery-screen');
|
||||
this.setupPhotoGalleryEventListeners();
|
||||
this.loadPhotoGallery();
|
||||
}
|
||||
|
||||
setupPhotoGalleryEventListeners() {
|
||||
// Back button
|
||||
const backBtn = document.getElementById('back-to-start-from-photos-btn');
|
||||
if (backBtn) {
|
||||
backBtn.onclick = () => this.showScreen('start-screen');
|
||||
}
|
||||
|
||||
// Action buttons
|
||||
const downloadAllBtn = document.getElementById('download-all-photos-btn');
|
||||
if (downloadAllBtn) {
|
||||
downloadAllBtn.onclick = () => this.downloadAllPhotos();
|
||||
}
|
||||
|
||||
const clearAllBtn = document.getElementById('clear-all-photos-btn');
|
||||
if (clearAllBtn) {
|
||||
clearAllBtn.onclick = () => this.clearAllPhotos();
|
||||
}
|
||||
|
||||
const settingsBtn = document.getElementById('photo-storage-settings-btn');
|
||||
if (settingsBtn) {
|
||||
settingsBtn.onclick = () => this.showPhotoSettings();
|
||||
}
|
||||
|
||||
// Filter controls
|
||||
const sessionFilter = document.getElementById('photo-session-filter');
|
||||
if (sessionFilter) {
|
||||
sessionFilter.onchange = () => this.filterPhotos();
|
||||
}
|
||||
|
||||
const sortOrder = document.getElementById('photo-sort-order');
|
||||
if (sortOrder) {
|
||||
sortOrder.onchange = () => this.filterPhotos();
|
||||
}
|
||||
|
||||
// Modal close buttons
|
||||
const closeDetailBtn = document.getElementById('close-photo-detail');
|
||||
if (closeDetailBtn) {
|
||||
closeDetailBtn.onclick = () => this.closePhotoDetail();
|
||||
}
|
||||
|
||||
const closeSettingsBtn = document.getElementById('close-photo-settings');
|
||||
if (closeSettingsBtn) {
|
||||
closeSettingsBtn.onclick = () => this.closePhotoSettings();
|
||||
}
|
||||
|
||||
// Photo detail modal actions
|
||||
const downloadBtn = document.getElementById('download-photo-btn');
|
||||
if (downloadBtn) {
|
||||
downloadBtn.onclick = () => this.downloadCurrentPhoto();
|
||||
}
|
||||
|
||||
const deleteBtn = document.getElementById('delete-photo-btn');
|
||||
if (deleteBtn) {
|
||||
deleteBtn.onclick = () => this.deleteCurrentPhoto();
|
||||
}
|
||||
|
||||
// Settings modal actions
|
||||
const saveSettingsBtn = document.getElementById('save-photo-settings-btn');
|
||||
if (saveSettingsBtn) {
|
||||
saveSettingsBtn.onclick = () => this.savePhotoSettings();
|
||||
}
|
||||
}
|
||||
|
||||
loadPhotoGallery() {
|
||||
const stats = this.webcamManager.getPhotoStats();
|
||||
this.updatePhotoStats(stats);
|
||||
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
const grid = document.getElementById('photo-grid');
|
||||
const noPhotosMsg = document.getElementById('no-photos-message');
|
||||
|
||||
if (photos.length === 0) {
|
||||
grid.style.display = 'none';
|
||||
noPhotosMsg.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
grid.style.display = 'grid';
|
||||
noPhotosMsg.style.display = 'none';
|
||||
|
||||
this.renderPhotoGrid(photos);
|
||||
}
|
||||
|
||||
updatePhotoStats(stats) {
|
||||
const countDisplay = document.getElementById('photo-count-display');
|
||||
const sizeDisplay = document.getElementById('storage-size-display');
|
||||
|
||||
if (countDisplay) {
|
||||
countDisplay.textContent = `${stats.count} photos`;
|
||||
}
|
||||
|
||||
if (sizeDisplay) {
|
||||
const sizeInKB = (stats.totalSize / 1024).toFixed(1);
|
||||
sizeDisplay.textContent = `${sizeInKB} KB used`;
|
||||
}
|
||||
}
|
||||
|
||||
renderPhotoGrid(photos) {
|
||||
const grid = document.getElementById('photo-grid');
|
||||
const sessionFilter = document.getElementById('photo-session-filter').value;
|
||||
const sortOrder = document.getElementById('photo-sort-order').value;
|
||||
|
||||
// Filter photos
|
||||
let filteredPhotos = photos;
|
||||
if (sessionFilter !== 'all') {
|
||||
filteredPhotos = photos.filter(photo => photo.sessionType === sessionFilter);
|
||||
}
|
||||
|
||||
// Sort photos
|
||||
switch (sortOrder) {
|
||||
case 'newest':
|
||||
filteredPhotos.sort((a, b) => b.timestamp - a.timestamp);
|
||||
break;
|
||||
case 'oldest':
|
||||
filteredPhotos.sort((a, b) => a.timestamp - b.timestamp);
|
||||
break;
|
||||
case 'session':
|
||||
filteredPhotos.sort((a, b) => a.sessionType.localeCompare(b.sessionType));
|
||||
break;
|
||||
}
|
||||
|
||||
// Render photo items
|
||||
grid.innerHTML = filteredPhotos.map(photo => this.createPhotoItem(photo)).join('');
|
||||
|
||||
// Add click listeners
|
||||
grid.querySelectorAll('.photo-item').forEach(item => {
|
||||
const photoId = item.dataset.photoId;
|
||||
item.onclick = () => this.showPhotoDetail(photoId);
|
||||
});
|
||||
}
|
||||
|
||||
createPhotoItem(photo) {
|
||||
const date = new Date(photo.timestamp).toLocaleDateString();
|
||||
const sessionName = this.formatSessionName(photo.sessionType);
|
||||
|
||||
return `
|
||||
<div class="photo-item" data-photo-id="${photo.id}">
|
||||
<img src="${photo.dataURL}" alt="Captured photo" loading="lazy">
|
||||
<div class="photo-item-info">
|
||||
<div class="photo-item-date">${date}</div>
|
||||
<div class="photo-item-session">${sessionName}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
formatSessionName(sessionType) {
|
||||
const sessionNames = {
|
||||
'dress-up-photo': 'Dress-up',
|
||||
'photography-studio': 'Studio',
|
||||
'custom': 'Custom'
|
||||
};
|
||||
return sessionNames[sessionType] || sessionType;
|
||||
}
|
||||
|
||||
filterPhotos() {
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
this.renderPhotoGrid(photos);
|
||||
}
|
||||
|
||||
showPhotoDetail(photoId) {
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
const photo = photos.find(p => p.id === photoId);
|
||||
if (!photo) return;
|
||||
|
||||
this.currentDetailPhoto = photo;
|
||||
|
||||
// Populate modal
|
||||
document.getElementById('photo-detail-image').src = photo.dataURL;
|
||||
document.getElementById('photo-detail-date').textContent = new Date(photo.timestamp).toLocaleString();
|
||||
document.getElementById('photo-detail-session').textContent = this.formatSessionName(photo.sessionType);
|
||||
document.getElementById('photo-detail-task').textContent = photo.taskId || 'Unknown';
|
||||
document.getElementById('photo-detail-size').textContent = `${Math.round(photo.size / 1024)} KB`;
|
||||
|
||||
// Show modal
|
||||
document.getElementById('photo-detail-modal').style.display = 'flex';
|
||||
}
|
||||
|
||||
closePhotoDetail() {
|
||||
document.getElementById('photo-detail-modal').style.display = 'none';
|
||||
this.currentDetailPhoto = null;
|
||||
}
|
||||
|
||||
downloadCurrentPhoto() {
|
||||
if (this.currentDetailPhoto) {
|
||||
this.webcamManager.downloadPhoto(this.currentDetailPhoto);
|
||||
}
|
||||
}
|
||||
|
||||
deleteCurrentPhoto() {
|
||||
if (!this.currentDetailPhoto) return;
|
||||
|
||||
if (confirm('Are you sure you want to delete this photo? This cannot be undone.')) {
|
||||
const success = this.webcamManager.deletePhoto(this.currentDetailPhoto.id);
|
||||
if (success) {
|
||||
this.closePhotoDetail();
|
||||
this.loadPhotoGallery(); // Refresh the gallery
|
||||
this.webcamManager.showNotification('Photo deleted', 'success');
|
||||
} else {
|
||||
this.webcamManager.showNotification('Failed to delete photo', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
downloadAllPhotos() {
|
||||
this.webcamManager.downloadAllPhotos();
|
||||
}
|
||||
|
||||
clearAllPhotos() {
|
||||
if (confirm('Are you sure you want to delete ALL photos? This cannot be undone.')) {
|
||||
const success = this.webcamManager.clearAllPhotos();
|
||||
if (success) {
|
||||
this.loadPhotoGallery(); // Refresh the gallery
|
||||
this.webcamManager.showNotification('All photos cleared', 'success');
|
||||
} else {
|
||||
this.webcamManager.showNotification('Failed to clear photos', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showPhotoSettings() {
|
||||
const stats = this.webcamManager.getPhotoStats();
|
||||
|
||||
// Update consent radio buttons
|
||||
const consentValue = stats.storageConsent;
|
||||
document.getElementById('consent-enable').checked = consentValue === 'true';
|
||||
document.getElementById('consent-disable').checked = consentValue === 'false';
|
||||
|
||||
// Update stats
|
||||
document.getElementById('settings-photo-count').textContent = stats.count;
|
||||
document.getElementById('settings-storage-size').textContent = `${(stats.totalSize / 1024).toFixed(1)} KB`;
|
||||
document.getElementById('settings-oldest-photo').textContent =
|
||||
stats.oldestPhoto ? new Date(stats.oldestPhoto).toLocaleDateString() : 'None';
|
||||
|
||||
// Show modal
|
||||
document.getElementById('photo-settings-modal').style.display = 'flex';
|
||||
}
|
||||
|
||||
closePhotoSettings() {
|
||||
document.getElementById('photo-settings-modal').style.display = 'none';
|
||||
}
|
||||
|
||||
savePhotoSettings() {
|
||||
const consentValue = document.querySelector('input[name="photo-consent"]:checked').value;
|
||||
localStorage.setItem('photoStorageConsent', consentValue);
|
||||
|
||||
this.closePhotoSettings();
|
||||
this.webcamManager.showNotification('Photo settings saved', 'success');
|
||||
}
|
||||
}
|
||||
|
||||
// Photo Gallery Management Methods
|
||||
TaskChallengeGame.prototype.showPhotoGallery = function() {
|
||||
this.showScreen('photo-gallery-screen');
|
||||
this.setupPhotoGalleryEventListeners();
|
||||
this.loadPhotoGallery();
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.setupPhotoGalleryEventListeners = function() {
|
||||
// Back button
|
||||
const backBtn = document.getElementById('back-to-start-from-photos-btn');
|
||||
if (backBtn) {
|
||||
backBtn.onclick = () => this.showScreen('start-screen');
|
||||
}
|
||||
|
||||
// Action buttons
|
||||
const downloadAllBtn = document.getElementById('download-all-photos-btn');
|
||||
if (downloadAllBtn) {
|
||||
downloadAllBtn.onclick = () => this.downloadAllPhotos();
|
||||
}
|
||||
|
||||
const clearAllBtn = document.getElementById('clear-all-photos-btn');
|
||||
if (clearAllBtn) {
|
||||
clearAllBtn.onclick = () => this.clearAllPhotos();
|
||||
}
|
||||
|
||||
const settingsBtn = document.getElementById('photo-storage-settings-btn');
|
||||
if (settingsBtn) {
|
||||
settingsBtn.onclick = () => this.showPhotoSettings();
|
||||
}
|
||||
|
||||
// Filter controls
|
||||
const sessionFilter = document.getElementById('photo-session-filter');
|
||||
if (sessionFilter) {
|
||||
sessionFilter.onchange = () => this.filterPhotos();
|
||||
}
|
||||
|
||||
const sortOrder = document.getElementById('photo-sort-order');
|
||||
if (sortOrder) {
|
||||
sortOrder.onchange = () => this.filterPhotos();
|
||||
}
|
||||
|
||||
// Modal close buttons
|
||||
const closeDetailBtn = document.getElementById('close-photo-detail');
|
||||
if (closeDetailBtn) {
|
||||
closeDetailBtn.onclick = () => this.closePhotoDetail();
|
||||
}
|
||||
|
||||
const closeSettingsBtn = document.getElementById('close-photo-settings');
|
||||
if (closeSettingsBtn) {
|
||||
closeSettingsBtn.onclick = () => this.closePhotoSettings();
|
||||
}
|
||||
|
||||
// Photo detail modal actions
|
||||
const downloadBtn = document.getElementById('download-photo-btn');
|
||||
if (downloadBtn) {
|
||||
downloadBtn.onclick = () => this.downloadCurrentPhoto();
|
||||
}
|
||||
|
||||
const deleteBtn = document.getElementById('delete-photo-btn');
|
||||
if (deleteBtn) {
|
||||
deleteBtn.onclick = () => this.deleteCurrentPhoto();
|
||||
}
|
||||
|
||||
// Settings modal actions
|
||||
const saveSettingsBtn = document.getElementById('save-photo-settings-btn');
|
||||
if (saveSettingsBtn) {
|
||||
saveSettingsBtn.onclick = () => this.savePhotoSettings();
|
||||
}
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.loadPhotoGallery = function() {
|
||||
const stats = this.webcamManager.getPhotoStats();
|
||||
this.updatePhotoStats(stats);
|
||||
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
const grid = document.getElementById('photo-grid');
|
||||
const noPhotosMsg = document.getElementById('no-photos-message');
|
||||
|
||||
if (photos.length === 0) {
|
||||
grid.style.display = 'none';
|
||||
noPhotosMsg.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
grid.style.display = 'grid';
|
||||
noPhotosMsg.style.display = 'none';
|
||||
|
||||
this.renderPhotoGrid(photos);
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.updatePhotoStats = function(stats) {
|
||||
const countDisplay = document.getElementById('photo-count-display');
|
||||
const sizeDisplay = document.getElementById('storage-size-display');
|
||||
|
||||
if (countDisplay) {
|
||||
countDisplay.textContent = `${stats.count} photos`;
|
||||
}
|
||||
|
||||
if (sizeDisplay) {
|
||||
const sizeInKB = (stats.totalSize / 1024).toFixed(1);
|
||||
sizeDisplay.textContent = `${sizeInKB} KB used`;
|
||||
}
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.renderPhotoGrid = function(photos) {
|
||||
const grid = document.getElementById('photo-grid');
|
||||
const sessionFilter = document.getElementById('photo-session-filter').value;
|
||||
const sortOrder = document.getElementById('photo-sort-order').value;
|
||||
|
||||
// Filter photos
|
||||
let filteredPhotos = photos;
|
||||
if (sessionFilter !== 'all') {
|
||||
filteredPhotos = photos.filter(photo => photo.sessionType === sessionFilter);
|
||||
}
|
||||
|
||||
// Sort photos
|
||||
switch (sortOrder) {
|
||||
case 'newest':
|
||||
filteredPhotos.sort((a, b) => b.timestamp - a.timestamp);
|
||||
break;
|
||||
case 'oldest':
|
||||
filteredPhotos.sort((a, b) => a.timestamp - b.timestamp);
|
||||
break;
|
||||
case 'session':
|
||||
filteredPhotos.sort((a, b) => a.sessionType.localeCompare(b.sessionType));
|
||||
break;
|
||||
}
|
||||
|
||||
// Render photo items
|
||||
grid.innerHTML = filteredPhotos.map(photo => this.createPhotoItem(photo)).join('');
|
||||
|
||||
// Add click listeners
|
||||
grid.querySelectorAll('.photo-item').forEach(item => {
|
||||
const photoId = item.dataset.photoId;
|
||||
item.onclick = () => this.showPhotoDetail(photoId);
|
||||
});
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.createPhotoItem = function(photo) {
|
||||
const date = new Date(photo.timestamp).toLocaleDateString();
|
||||
const sessionName = this.formatSessionName(photo.sessionType);
|
||||
|
||||
return `
|
||||
<div class="photo-item" data-photo-id="${photo.id}">
|
||||
<img src="${photo.dataURL}" alt="Captured photo" loading="lazy">
|
||||
<div class="photo-item-info">
|
||||
<div class="photo-item-date">${date}</div>
|
||||
<div class="photo-item-session">${sessionName}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.formatSessionName = function(sessionType) {
|
||||
const sessionNames = {
|
||||
'dress-up-photo': 'Dress-up',
|
||||
'photography-studio': 'Studio',
|
||||
'custom': 'Custom'
|
||||
};
|
||||
return sessionNames[sessionType] || sessionType;
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.filterPhotos = function() {
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
this.renderPhotoGrid(photos);
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.showPhotoDetail = function(photoId) {
|
||||
const photos = this.webcamManager.getSavedPhotos();
|
||||
const photo = photos.find(p => p.id === photoId);
|
||||
if (!photo) return;
|
||||
|
||||
this.currentDetailPhoto = photo;
|
||||
|
||||
// Populate modal
|
||||
document.getElementById('photo-detail-image').src = photo.dataURL;
|
||||
document.getElementById('photo-detail-date').textContent = new Date(photo.timestamp).toLocaleString();
|
||||
document.getElementById('photo-detail-session').textContent = this.formatSessionName(photo.sessionType);
|
||||
document.getElementById('photo-detail-task').textContent = photo.taskId || 'Unknown';
|
||||
document.getElementById('photo-detail-size').textContent = `${Math.round(photo.size / 1024)} KB`;
|
||||
|
||||
// Show modal
|
||||
document.getElementById('photo-detail-modal').style.display = 'flex';
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.closePhotoDetail = function() {
|
||||
document.getElementById('photo-detail-modal').style.display = 'none';
|
||||
this.currentDetailPhoto = null;
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.downloadCurrentPhoto = function() {
|
||||
if (this.currentDetailPhoto) {
|
||||
this.webcamManager.downloadPhoto(this.currentDetailPhoto);
|
||||
}
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.deleteCurrentPhoto = function() {
|
||||
if (!this.currentDetailPhoto) return;
|
||||
|
||||
if (confirm('Are you sure you want to delete this photo? This cannot be undone.')) {
|
||||
const success = this.webcamManager.deletePhoto(this.currentDetailPhoto.id);
|
||||
if (success) {
|
||||
this.closePhotoDetail();
|
||||
this.loadPhotoGallery(); // Refresh the gallery
|
||||
this.webcamManager.showNotification('Photo deleted', 'success');
|
||||
} else {
|
||||
this.webcamManager.showNotification('Failed to delete photo', 'error');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.downloadAllPhotos = function() {
|
||||
this.webcamManager.downloadAllPhotos();
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.clearAllPhotos = function() {
|
||||
if (confirm('Are you sure you want to delete ALL photos? This cannot be undone.')) {
|
||||
const success = this.webcamManager.clearAllPhotos();
|
||||
if (success) {
|
||||
this.loadPhotoGallery(); // Refresh the gallery
|
||||
this.webcamManager.showNotification('All photos cleared', 'success');
|
||||
} else {
|
||||
this.webcamManager.showNotification('Failed to clear photos', 'error');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.showPhotoSettings = function() {
|
||||
const stats = this.webcamManager.getPhotoStats();
|
||||
|
||||
// Update consent radio buttons
|
||||
const consentValue = stats.storageConsent;
|
||||
document.getElementById('consent-enable').checked = consentValue === 'true';
|
||||
document.getElementById('consent-disable').checked = consentValue === 'false';
|
||||
|
||||
// Update stats
|
||||
document.getElementById('settings-photo-count').textContent = stats.count;
|
||||
document.getElementById('settings-storage-size').textContent = `${(stats.totalSize / 1024).toFixed(1)} KB`;
|
||||
document.getElementById('settings-oldest-photo').textContent =
|
||||
stats.oldestPhoto ? new Date(stats.oldestPhoto).toLocaleDateString() : 'None';
|
||||
|
||||
// Show modal
|
||||
document.getElementById('photo-settings-modal').style.display = 'flex';
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.closePhotoSettings = function() {
|
||||
document.getElementById('photo-settings-modal').style.display = 'none';
|
||||
};
|
||||
|
||||
TaskChallengeGame.prototype.savePhotoSettings = function() {
|
||||
const consentValue = document.querySelector('input[name="photo-consent"]:checked').value;
|
||||
localStorage.setItem('photoStorageConsent', consentValue);
|
||||
|
||||
this.closePhotoSettings();
|
||||
this.webcamManager.showNotification('Photo settings saved', 'success');
|
||||
};
|
||||
|
||||
// Annoyance Management Methods - Phase 2: Advanced Message Management
|
||||
TaskChallengeGame.prototype.showAnnoyanceManagement = function() {
|
||||
this.showScreen('annoyance-management-screen');
|
||||
|
|
|
|||
Loading…
Reference in New Issue