Add Image Thumbnails and Previews for better image optimization update view image modal to JS and allow to move between images using previous and next arrows

This commit is contained in:
johnnyq 2024-12-08 15:22:37 -05:00
parent c4870e49cf
commit 1d8a78b279
6 changed files with 252 additions and 34 deletions

View File

@ -1,17 +1,25 @@
<div class="modal" id="viewFileModal<?php echo $file_id; ?>" tabindex="-1">
<div class="modal-dialog modal-xl ">
<div class="modal-content bg-dark">
<div class="modal" id="viewFileModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content bg-dark text-white">
<div class="modal-header">
<h5 class="modal-title"><i class="fa fa-fw fa-image mr-2"></i><?php echo $file_name; ?></h5>
<h6 class="modal-title" id="modalTitle"></h6>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="position-relative text-center">
<!-- Left arrow -->
<button type="button" class="btn btn-dark position-absolute" style="left:10px; top:50%; transform:translateY(-50%);" onclick="prevFile()">
<i class="fas fa-chevron-left"></i>
</button>
<div style="text-align: center;">
<img class="img-fluid" src="<?php echo "uploads/clients/$client_id/$file_reference_name"; ?>">
<img id="modalImage" class="img-fluid my-3" src="" alt="">
<!-- Right arrow -->
<button type="button" class="btn btn-dark position-absolute" style="right:10px; top:50%; transform:translateY(-50%);" onclick="nextFile()">
<i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
</div>
</div>

View File

@ -303,10 +303,7 @@ while ($folder_id > 0) {
<hr>
<?php
if ($num_of_files == 0) {
echo "<div style='text-align: center;'><h3 class='text-secondary'>No Records Here</h3></div>";
}
if($view == 1){
?>
@ -314,7 +311,7 @@ while ($folder_id > 0) {
<div class="row">
<?php
$files = [];
while ($row = mysqli_fetch_array($sql)) {
$file_id = intval($row['file_id']);
$file_name = nullable_htmlentities($row['file_name']);
@ -324,25 +321,67 @@ while ($folder_id > 0) {
$file_size_KB = number_format($file_size / 1024);
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_uploaded_by = nullable_htmlentities($row['user_name']);
$file_has_thumbnail = intval($row['file_has_thumbnail']);
$file_has_preview = intval($row['file_has_preview']);
$file_thumbnail_source = $file_reference_name;
if ($file_has_thumbnail == 1) {
$file_thumbnail_source = "thumbnail_$file_reference_name";
}
$file_preview_source = $file_reference_name;
if ($file_has_preview == 1) {
$file_preview_source = "preview_$file_reference_name";
}
// Store file data into an array for JS
$files[] = [
'id' => $file_id,
'name' => $file_name,
'preview' => "uploads/clients/$client_id/$file_preview_source"
];
?>
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-6 mb-3">
<div class="card">
<a href="#" data-toggle="modal" data-target="#viewFileModal<?php echo $file_id; ?>">
<img class="img-fluid" src="<?php echo "uploads/clients/$client_id/$file_reference_name"; ?>" alt="<?php echo $file_reference_name ?>">
</a>
<div class="card-footer bg-dark text-white p-1" style="text-align: center;">
<a href="<?php echo "uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>" class="text-white float-left ml-1"><i class="fa fa-cloud-download-alt"></i></a>
<a href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)" class="text-white float-left ml-1"><i class="fa fa-share"></i></a>
<small><?php echo $file_name; ?></small>
<?php if ($session_user_role == 3) { ?>
<a href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)" class="text-white float-right mr-1"><i class="fa fa-times"></i></a>
<?php } ?>
<div class="col-xl-2 col-lg-2 col-md-6 col-sm-6 mb-3 text-center">
<a href="#" onclick="openModal(<?php echo count($files)-1; ?>)"><!-- passing the index -->
<img class="img-thumbnail" src="<?php echo "uploads/clients/$client_id/$file_reference_name"; ?>" alt="<?php echo $file_reference_name ?>">
</a>
<div>
<div class="dropdown float-right">
<button class="btn btn-link btn-sm" type="button" data-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="<?php echo "uploads/clients/$client_id/$file_reference_name"; ?>" download="<?php echo $file_name; ?>">
<i class="fas fa-fw fa-cloud-download-alt mr-2"></i>Download
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#shareModal" onclick="populateShareModal(<?php echo "$client_id, 'File', $file_id"; ?>)">
<i class="fas fa-fw fa-share mr-2"></i>Share
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#renameFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-edit mr-2"></i>Rename
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#moveFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move
</a>
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#linkAssetToFileModal<?php echo $file_id; ?>">
<i class="fas fa-fw fa-desktop mr-2"></i>Asset
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger confirm-link" href="post.php?archive_file=<?php echo $file_id; ?>">
<i class="fas fa-fw fa-archive mr-2"></i>Archive
</a>
<?php if ($session_user_role == 3) { ?>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="#" data-toggle="modal" data-target="#deleteFileModal" onclick="populateFileDeleteModal(<?php echo "$file_id , '$file_name'" ?>)">
<i class="fas fa-fw fa-trash mr-2"></i>Delete
</a>
<?php } ?>
</div>
</div>
<small class="text-secondary"><?php echo $file_name; ?></small>
</div>
</div>
@ -351,6 +390,11 @@ while ($folder_id > 0) {
}
?>
<script>
// Pass PHP array to JavaScript
var files = <?php echo json_encode($files); ?>;
var currentIndex = 0; // Keep track of which file is displayed
</script>
</div>
<?php } else { ?>
@ -428,7 +472,9 @@ while ($folder_id > 0) {
$file_size = intval($row['file_size']);
$file_size_KB = number_format($file_size / 1024);
$file_mime_type = nullable_htmlentities($row['file_mime_type']);
$file_uploaded_by = nullable_htmlentities($row['user_name']);
$file_size = intval($row['file_size']);
$file_has_thumbnail = intval($row['file_has_thumbnail']);
$file_has_preview = intval($row['file_has_preview']);
$file_created_at = nullable_htmlentities($row['file_created_at']);
$file_folder_id = intval($row['file_folder_id']);
@ -558,6 +604,29 @@ while ($folder_id > 0) {
</div>
</div>
<script>
function openModal(index) {
currentIndex = index;
updateModalContent();
$('#viewFileModal').modal('show');
}
function updateModalContent() {
document.getElementById('modalTitle').innerText = files[currentIndex].name;
document.getElementById('modalImage').src = files[currentIndex].preview;
}
function nextFile() {
currentIndex = (currentIndex + 1) % files.length; // loop around
updateModalContent();
}
function prevFile() {
currentIndex = (currentIndex - 1 + files.length) % files.length; // loop around
updateModalContent();
}
</script>
<script src="js/bulk_actions.js"></script>
<?php

View File

@ -2303,7 +2303,7 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.6.8'");
}
if (CURRENT_DATABASE_VERSION == '1.6.8') {
if (CURRENT_DATABASE_VERSION == '1.6.8') {
// Create New Vendor Templates Table this eventual be used to seperate templates out of the vendors table
mysqli_query($mysqli, "CREATE TABLE `vendor_templates` (`vendor_template_id` int(11) AUTO_INCREMENT PRIMARY KEY,
@ -2321,10 +2321,18 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) {
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.6.9'");
}
// if (CURRENT_DATABASE_VERSION == '1.6.9') {
// // Insert queries here required to update to DB version 1.7.0
if (CURRENT_DATABASE_VERSION == '1.6.9') {
mysqli_query($mysqli, "ALTER TABLE `files` ADD `file_has_thumbnail` TINYINT(1) NOT NULL DEFAULT 0 AFTER `file_mime_type`");
mysqli_query($mysqli, "ALTER TABLE `files` ADD `file_has_preview` TINYINT(1) NOT NULL DEFAULT 0 AFTER `file_has_thumbnail`");
mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.0'");
}
// if (CURRENT_DATABASE_VERSION == '1.7.0') {
// // Insert queries here required to update to DB version 1.7.1
// // Then, update the database to the next sequential version
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.0'");
// mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.7.1'");
// }
} else {

View File

@ -5,4 +5,4 @@
* It is used in conjunction with database_updates.php
*/
DEFINE("LATEST_DATABASE_VERSION", "1.6.9");
DEFINE("LATEST_DATABASE_VERSION", "1.7.0");

4
db.sql
View File

@ -780,6 +780,8 @@ CREATE TABLE `files` (
`file_size` bigint(20) unsigned NOT NULL DEFAULT 0,
`file_hash` varchar(200) DEFAULT NULL,
`file_mime_type` varchar(100) DEFAULT NULL,
`file_has_thumbnail` tinyint(1) NOT NULL DEFAULT 0,
`file_has_preview` tinyint(1) NOT NULL DEFAULT 0,
`file_important` tinyint(1) NOT NULL DEFAULT 0,
`file_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`file_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
@ -2284,4 +2286,4 @@ CREATE TABLE `vendors` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-12-07 15:37:47
-- Dump completed on 2024-12-08 15:20:52

View File

@ -51,6 +51,119 @@ if (isset($_POST['upload_files'])) {
$file_id = mysqli_insert_id($mysqli);
// If the file is an image, create a thumbnail and an optimized preview image
if (in_array($file_extension, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
// Thumbnail dimensions
$thumbnail_width = 200;
$thumbnail_height = 200;
// Optimized preview dimensions
$preview_max_width = 1200;
$preview_max_height = 1200;
// Get original dimensions
list($orig_width, $orig_height) = getimagesize($dest_path);
// Create image resource from the original file
switch ($file_extension) {
case 'jpg':
case 'jpeg':
$src_img = imagecreatefromjpeg($dest_path);
break;
case 'png':
$src_img = imagecreatefrompng($dest_path);
break;
case 'gif':
$src_img = imagecreatefromgif($dest_path);
break;
case 'webp':
$src_img = imagecreatefromwebp($dest_path);
break;
}
if ($src_img) {
// -------------------------
// CREATE THUMBNAIL
// -------------------------
$thumb_img = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($thumb_img, $src_img, 0, 0, 0, 0,
$thumbnail_width, $thumbnail_height,
$orig_width, $orig_height);
$thumbnail_file_name = 'thumbnail_' . $file_reference_name;
$thumb_path = $upload_file_dir . $thumbnail_file_name;
// Save thumbnail to disk
switch ($file_extension) {
case 'jpg':
case 'jpeg':
imagejpeg($thumb_img, $thumb_path, 80);
break;
case 'png':
imagepng($thumb_img, $thumb_path);
break;
case 'gif':
imagegif($thumb_img, $thumb_path);
break;
case 'webp':
imagewebp($thumb_img, $thumb_path);
break;
}
imagedestroy($thumb_img);
mysqli_query($mysqli,"UPDATE files SET file_has_thumbnail = 1 WHERE file_id = $file_id");
// -------------------------
// CREATE OPTIMIZED PREVIEW IMAGE
// -------------------------
$aspect_ratio = $orig_width / $orig_height;
if ($orig_width <= $preview_max_width && $orig_height <= $preview_max_height) {
$preview_new_width = $orig_width;
$preview_new_height = $orig_height;
} elseif ($aspect_ratio > 1) {
// Wider than tall
$preview_new_width = $preview_max_width;
$preview_new_height = (int)($preview_max_width / $aspect_ratio);
} else {
// Taller or square
$preview_new_height = $preview_max_height;
$preview_new_width = (int)($preview_max_height * $aspect_ratio);
}
$preview_img = imagecreatetruecolor($preview_new_width, $preview_new_height);
imagecopyresampled($preview_img, $src_img, 0, 0, 0, 0,
$preview_new_width, $preview_new_height,
$orig_width, $orig_height);
$preview_file_name = 'preview_' . $file_reference_name;
$preview_path = $upload_file_dir . $preview_file_name;
switch ($file_extension) {
case 'jpg':
case 'jpeg':
// Lower quality for optimization (70 is example)
imagejpeg($preview_img, $preview_path, 70);
break;
case 'png':
// Higher compression level (0-9), 7 is an example
imagepng($preview_img, $preview_path, 7);
break;
case 'gif':
imagegif($preview_img, $preview_path);
break;
case 'webp':
imagewebp($preview_img, $preview_path, 70);
break;
}
imagedestroy($preview_img);
imagedestroy($src_img);
mysqli_query($mysqli,"UPDATE files SET file_has_preview = 1 WHERE file_id = $file_id");
}
}
// Logging
logAction("File", "Upload", "$session_name uploaded file $file_name", $client_id, $file_id);
@ -155,9 +268,18 @@ if (isset($_POST['delete_file'])) {
$client_id = intval($row['file_client_id']);
$file_name = sanitizeInput($row['file_name']);
$file_reference_name = sanitizeInput($row['file_reference_name']);
$file_has_thumbnail = intval($row['file_has_thumbnail']);
$file_has_preview = intval($row['file_has_preview']);
unlink("uploads/clients/$client_id/$file_reference_name");
if ($file_has_thumbnail == 1) {
unlink("uploads/clients/$client_id/thumbnail_$file_reference_name");
}
if ($file_has_preview == 1) {
unlink("uploads/clients/$client_id/preview_$file_reference_name");
}
mysqli_query($mysqli,"DELETE FROM files WHERE file_id = $file_id");
//Logging
@ -190,9 +312,18 @@ if (isset($_POST['bulk_delete_files'])) {
$client_id = intval($row['file_client_id']);
$file_name = sanitizeInput($row['file_name']);
$file_reference_name = sanitizeInput($row['file_reference_name']);
$file_has_thumbnail = intval($row['file_has_thumbnail']);
$file_has_preview = intval($row['file_has_preview']);
unlink("uploads/clients/$client_id/$file_reference_name");
if ($file_has_thumbnail == 1) {
unlink("uploads/clients/$client_id/thumbnail_$file_reference_name");
}
if ($file_has_preview == 1) {
unlink("uploads/clients/$client_id/preview_$file_reference_name");
}
mysqli_query($mysqli,"DELETE FROM files WHERE file_id = $file_id");
// Log each invidual file deletion