colapsable fotos and comments section in contribution popup, comment count in popup and sidebar

This commit was merged in pull request #11.
This commit is contained in:
2026-04-27 14:48:05 +02:00
parent c39667e368
commit f23897018c
2 changed files with 116 additions and 23 deletions

View File

@@ -388,7 +388,7 @@ function styleLinePolygon(feature) {
// Block 9: Feature Popups for Read, Edit, Delete and Vote
// =====================================================================
// Builds Popup HTML for Features
// Builds Popup HTML for Features called every Time the Popup opens
function buildPopupHtml(feature) {
const props = feature.properties;
const cat = CATEGORIES[props.category] || CATEGORIES.other;
@@ -405,18 +405,26 @@ function buildPopupHtml(feature) {
'<div class="popup-detail-title">' + escapeHtml(props.title) + '</div>' +
(props.description ? '<div class="popup-detail-description">' + escapeHtml(props.description) + '</div>' : '');
// Shows Photo if available
// Photo Toggle Button including hidden Photo
if (props.photo_path) {
html += '<div class="popup-detail-photo">' +
'<img src="' + escapeHtml(props.photo_path) + '" alt="Foto" style="max-width:100%;border-radius:6px;margin-bottom:8px;cursor:pointer;" onclick="window.open(\'' + escapeHtml(props.photo_path) + '\', \'_blank\')">' +
html += '<div class="popup-photo-container" id="photo-container-' + props.contribution_id + '" style="display:none;">' +
'<img src="' + escapeHtml(props.photo_path) + '" alt="Foto" class="popup-photo-img" onclick="window.open(\'' + escapeHtml(props.photo_path) + '\', \'_blank\')">' +
'</div>' +
'<div class="popup-photo-toggle">' +
'<button class="popup-photo-btn" onclick="togglePhoto(' + props.contribution_id + ')">' +
'<i class="fa-solid fa-camera"></i> <span id="photo-label-' + props.contribution_id + '">Foto anzeigen</span>' +
'</button>' +
'</div>';
}
// Meta Information
html += '<div class="popup-detail-meta">' +
'<i class="fa-solid fa-user"></i> ' + escapeHtml(props.author_name) +
' &middot; <i class="fa-solid fa-calendar"></i> ' + dateStr +
'</div>' +
'<div class="popup-detail-votes">' +
'</div>';
// Vote Buttons
html += '<div class="popup-detail-votes">' +
'<button class="popup-vote-btn' + (userVotes[props.contribution_id] === 'like' ? ' liked' : '') + '" id="vote-like-' + props.contribution_id + '" onclick="voteContribution(' + props.contribution_id + ', \'like\')" title="Gefällt mir">' +
'<i class="fa-solid fa-thumbs-up"></i> <span id="likes-' + props.contribution_id + '">' + props.likes_count + '</span>' +
'</button>' +
@@ -433,15 +441,17 @@ function buildPopupHtml(feature) {
'</div>';
}
// Comments Section
html += '<div class="popup-comments" id="comments-' + props.contribution_id + '">' +
'<div class="popup-comments-header">' +
'<i class="fa-solid fa-comments"></i> Kommentare' +
' <span id="comment-count-' + props.contribution_id + '">...</span>' +
// Collapsible Comments Section
const commentCount = props.comment_count || 0;
html += '<div class="popup-comments">' +
'<div class="popup-comments-header" onclick="toggleComments(' + props.contribution_id + ')">' +
'<i class="fa-solid fa-comments"></i> Kommentare (' + commentCount + ')' +
' <i class="fa-solid fa-chevron-down popup-comments-toggle" id="comments-toggle-' + props.contribution_id + '"></i>' +
'</div>' +
'<div id="comments-section-' + props.contribution_id + '" style="display:none;">' +
'<div id="comments-list-' + props.contribution_id + '" class="popup-comments-list"></div>';
// Comment Form only for logged-in Users
// Comment Input for logged-in Users
if (currentUser) {
html += '<div class="popup-comment-form">' +
'<input type="text" id="comment-input-' + props.contribution_id + '" class="popup-comment-input" placeholder="Kommentar schreiben..." maxlength="1000">' +
@@ -451,7 +461,7 @@ function buildPopupHtml(feature) {
'</div>';
}
html += '</div></div>';
html += '</div></div></div>';
return html;
}
@@ -775,6 +785,7 @@ function updateContributionsList() {
'<span class="contribution-card-votes">' +
'<span title="Likes"><i class="fa-solid fa-thumbs-up"></i> ' + props.likes_count + '</span>' +
'<span title="Dislikes"><i class="fa-solid fa-thumbs-down"></i> ' + props.dislikes_count + '</span>' +
'<span title="Kommentare"><i class="fa-solid fa-comment"></i> ' + (props.comment_count || 0) + '</span>' +
'</span>' +
'</div>' +
'</div>';
@@ -1133,6 +1144,40 @@ function deleteComment(commentId, contributionId) {
});
}
// Toggles Photo Visibility in Popup
function togglePhoto(contributionId) {
const container = document.getElementById('photo-container-' + contributionId);
const label = document.getElementById('photo-label-' + contributionId);
if (!container) return;
if (container.style.display === 'none') {
container.style.display = 'block';
label.textContent = 'Foto verbergen';
} else {
container.style.display = 'none';
label.textContent = 'Foto anzeigen';
}
}
// Toggles Comments Section Visibility in Popup
function toggleComments(contributionId) {
const section = document.getElementById('comments-section-' + contributionId);
const toggle = document.getElementById('comments-toggle-' + contributionId);
if (!section) return;
if (section.style.display === 'none') {
section.style.display = 'block';
toggle.classList.remove('fa-chevron-down');
toggle.classList.add('fa-chevron-up');
// Loads Comments
loadComments(contributionId);
} else {
section.style.display = 'none';
toggle.classList.remove('fa-chevron-up');
toggle.classList.add('fa-chevron-down');
}
}
// =====================================================================
// Block 16: Application Startup

View File

@@ -630,8 +630,47 @@ select.form-input { cursor: pointer; }
/* -----------------------------------------------------------------
4.8 Popup Comments
4.8 Popup Photo and Comments
----------------------------------------------------------------- */
/* Photo Toggle Button */
.popup-photo-toggle {
margin: var(--space-sm) 0;
}
.popup-photo-btn {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 12px;
border: 1px solid var(--color-border);
border-radius: 16px;
background: var(--color-surface);
cursor: pointer;
font-size: 0.78rem;
color: var(--color-text-secondary);
font-family: var(--font-body);
transition: all var(--transition-fast);
}
.popup-photo-btn:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
/* Photo Container */
.popup-photo-container { margin-bottom: var(--space-sm); }
.popup-photo-img {
max-width: 100%;
max-height: 180px;
object-fit: cover;
border-radius: 6px;
cursor: pointer;
border: 1px solid var(--color-border);
}
/* Comments Section */
.popup-comments {
margin-top: var(--space-sm);
padding-top: var(--space-sm);
@@ -642,12 +681,26 @@ select.form-input { cursor: pointer; }
font-size: 0.8rem;
font-weight: 600;
color: var(--color-text-secondary);
margin-bottom: var(--space-sm);
cursor: pointer;
display: flex;
align-items: center;
gap: 4px;
padding: 4px 0;
transition: color var(--transition-fast);
}
.popup-comments-header:hover { color: var(--color-primary); }
.popup-comments-toggle {
font-size: 0.65rem;
margin-left: auto;
transition: transform 200ms ease;
}
.popup-comments-list {
max-height: 150px;
overflow-y: auto;
margin-top: var(--space-sm);
}
.popup-comment {
@@ -669,10 +722,7 @@ select.form-input { cursor: pointer; }
line-height: 1.4;
}
.popup-comment-delete {
color: var(--color-error);
font-size: 0.7rem;
}
.popup-comment-delete { color: var(--color-error); font-size: 0.7rem; }
.popup-comment-empty {
font-size: 0.8rem;
@@ -697,9 +747,7 @@ select.form-input { cursor: pointer; }
outline: none;
}
.popup-comment-input:focus {
border-color: var(--color-primary);
}
.popup-comment-input:focus { border-color: var(--color-primary); }
.popup-comment-submit {
border: none;