ajout d'une fonction pour afficher des images en "top" de leur galerie

This commit is contained in:
Esenjin 2025-01-03 15:16:07 +01:00
parent 018c99e273
commit 97a315064a
4 changed files with 150 additions and 48 deletions

View File

@ -67,7 +67,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['error_message'] = implode("\n", $errors);
}
break;
case 'toggle_top':
$image = $_POST['image'] ?? '';
if ($image) {
$imagePath = $currentPath . '/' . basename($image);
if (isSecurePath($imagePath) && file_exists($imagePath)) {
$info = pathinfo($imagePath);
$isTop = strpos($info['filename'], '--top--') !== false;
if ($isTop) {
// Enlever le tag top
$newName = str_replace('--top--', '', $info['filename']) . '.' . $info['extension'];
} else {
// Ajouter le tag top
$newName = $info['filename'] . '--top--.' . $info['extension'];
}
$newPath = $currentPath . '/' . $newName;
if (rename($imagePath, $newPath)) {
$_SESSION['success_message'] = $isTop ? "Image retirée des tops." : "Image mise en top.";
} else {
$_SESSION['error_message'] = "Erreur lors de la modification du statut top.";
}
}
}
break;
case 'delete':
$images = $_POST['images'] ?? [];
$deleteCount = 0;
@ -174,27 +200,36 @@ $images = array_map(function($img) {
<form method="post" id="deleteForm">
<input type="hidden" name="action" value="delete">
<div class="images-grid">
<?php foreach($images as $image):
// Déterminer si nous sommes dans le dossier du carrousel
$isCarousel = strpos($currentPath, 'img_carrousel') !== false;
if ($isCarousel) {
$imageUrl = getBaseUrl() . '/img_carrousel/' . $image;
} else {
$imageUrl = getBaseUrl() . '/liste_albums/' . substr($currentPath, strpos($currentPath, '/liste_albums/') + strlen('/liste_albums/')) . '/' . $image;
}
?>
<div class="image-item">
<input type="checkbox" name="images[]" value="<?php echo htmlspecialchars($image); ?>"
class="image-checkbox" onchange="updateDeleteButton()">
<img src="<?php echo htmlspecialchars($imageUrl); ?>"
alt="<?php echo htmlspecialchars($image); ?>" loading="lazy">
<div class="image-actions">
<button type="button" onclick="deleteImage('<?php echo htmlspecialchars($image); ?>')"
class="tree-button tree-button-danger">🗑️</button>
</div>
</div>
<?php endforeach; ?>
<?php foreach($images as $image):
$isCarousel = strpos($currentPath, 'img_carrousel') !== false;
if ($isCarousel) {
$imageUrl = getBaseUrl() . '/img_carrousel/' . $image;
} else {
$imageUrl = getBaseUrl() . '/liste_albums/' . substr($currentPath, strpos($currentPath, '/liste_albums/') + strlen('/liste_albums/')) . '/' . $image;
}
?>
<div class="image-item">
<input type="checkbox" name="images[]" value="<?php echo htmlspecialchars($image); ?>"
class="image-checkbox" onchange="updateDeleteButton()">
<div class="image-wrapper">
<img src="<?php echo htmlspecialchars($imageUrl); ?>"
alt="<?php echo htmlspecialchars($image); ?>" loading="lazy">
<div class="image-actions">
<?php
$isTop = strpos($image, '--top--') !== false;
?>
<button type="button" onclick="toggleTop('<?php echo htmlspecialchars($image); ?>')"
class="tree-button <?php echo $isTop ? 'tree-button-top' : ''; ?>"
title="<?php echo $isTop ? 'Retirer des tops' : 'Mettre en top'; ?>">
</button>
<button type="button" onclick="deleteImage('<?php echo htmlspecialchars($image); ?>')"
class="tree-button tree-button-danger">🗑️</button>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</form>
</div>
@ -232,6 +267,17 @@ $images = array_map(function($img) {
uploadForm.submit();
}
});
// Fonction de mise en top
function toggleTop(imageName) {
const form = document.createElement('form');
form.method = 'post';
form.innerHTML = `
<input type="hidden" name="action" value="toggle_top">
<input type="hidden" name="image" value="${imageName}">
`;
document.body.appendChild(form);
form.submit();
}
// Gestion de la suppression
function deleteImage(imageName) {

View File

@ -28,10 +28,18 @@ foreach (new DirectoryIterator($currentPath) as $file) {
}
}
// Tri modifié pour mettre les images "top" en premier
usort($images, function($a, $b) {
$pathA = realpath('.') . str_replace(getBaseUrl(), '', $a);
$pathB = realpath('.') . str_replace(getBaseUrl(), '', $b);
return filectime($pathB) - filectime($pathA);
$isTopA = strpos(basename($a), '--top--') !== false;
$isTopB = strpos(basename($b), '--top--') !== false;
if ($isTopA && !$isTopB) return -1; // a est top, pas b
if (!$isTopA && $isTopB) return 1; // b est top, pas a
// Si les deux sont top ou aucun n'est top, on garde le tri par date
$pathA = realpath('.') . str_replace(getBaseUrl(), '', $a);
$pathB = realpath('.') . str_replace(getBaseUrl(), '', $b);
return filectime($pathB) - filectime($pathA);
});
$headerImage = !empty($images) ? $images[0] : null;
@ -98,8 +106,10 @@ if (!isSecurePath($parentPath)) {
</div>
<div class="gallery-grid" id="gallery-grid">
<?php foreach($images as $image): ?>
<div class="gallery-item">
<?php foreach($images as $image):
$isTop = strpos(basename($image), '--top--') !== false;
?>
<div class="gallery-item<?php echo $isTop ? ' gallery-item-top' : ''; ?>">
<a href="partage.php?image=<?php echo urlencode($image); ?>" target="_blank">
<img src="<?php echo htmlspecialchars($image); ?>"
alt="Image de la galerie"
@ -108,7 +118,7 @@ if (!isSecurePath($parentPath)) {
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>

View File

@ -424,6 +424,15 @@ body {
color: #ffffff;
}
/* Styles pour le bouton top */
.tree-button-top {
background-color: rgba(33, 150, 243, 0.7) !important;
}
.tree-button-top:hover {
background-color: rgba(33, 150, 243, 0.9) !important;
}
/* Styles pour le dossier carousel */
.carousel-folder > .tree-item-content {
background: rgba(255, 140, 0, 0.1);
@ -605,18 +614,26 @@ body {
/* Styles pour les listes d'images */
.images-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
padding: 1rem;
}
.image-item {
position: relative;
aspect-ratio: 1;
width: 100%;
padding-bottom: 100%;
background-color: #2a2a2a;
border-radius: 0.5rem;
overflow: hidden;
background-color: #2a2a2a;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.image-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.image-item:hover {
@ -626,36 +643,51 @@ body {
}
.image-item img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.image-item:hover img {
transform: scale(1.1);
}
.image-checkbox {
position: absolute;
top: 0.5rem;
left: 0.5rem;
z-index: 2;
width: 24px;
height: 24px;
cursor: pointer;
accent-color: #2196f3;
}
.image-checkbox:hover {
transform: scale(1.1);
}
.image-actions {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 2;
display: flex;
gap: 0.5rem;
}
.image-checkbox {
position: absolute;
top: 0.5rem;
left: 0.5rem;
z-index: 3;
width: 24px;
height: 24px;
cursor: pointer;
accent-color: #2196f3;
opacity: 0.8;
}
.image-checkbox:hover {
transform: scale(1.1);
opacity: 1;
}
.image-actions {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 2;
display: flex;
gap: 0.5rem;
}
.upload-zone {

View File

@ -403,6 +403,20 @@ body {
display: block;
}
.gallery-item-top {
/* Contour bleu */
border: 4px solid #2196f3;
/* Animation subtile au survol */
position: relative;
z-index: 2;
transition: all 0.3s ease;
}
.gallery-item-top:hover {
transform: translateY(-8px);
box-shadow: 0 12px 24px rgba(33, 150, 243, 0.3);
}
/* Styles pour la page de partage */
.share-page {
background-color: rgba(0, 0, 0, 0.9);