From 9cfa3df03e05c04aedcad535476655b263880e6d Mon Sep 17 00:00:00 2001 From: Rostislav Raykov Date: Mon, 2 Dec 2024 14:41:36 +0200 Subject: [PATCH] added a checkbox to hide the file from the file list view --- .../controller/FileViewController.java | 60 +++++++++---- .../quickdrop/entity/FileEntity.java | 2 + .../quickdrop/model/FileEntityView.java | 2 + .../quickdrop/repository/FileRepository.java | 8 +- .../quickdrop/service/FileService.java | 20 +++++ src/main/resources/static/js/upload.js | 11 +++ .../resources/templates/admin/dashboard.html | 89 ++++++++++++------- src/main/resources/templates/fileView.html | 19 +++- 8 files changed, 158 insertions(+), 53 deletions(-) diff --git a/src/main/java/org/rostislav/quickdrop/controller/FileViewController.java b/src/main/java/org/rostislav/quickdrop/controller/FileViewController.java index ce8b4a0..ed9db87 100644 --- a/src/main/java/org/rostislav/quickdrop/controller/FileViewController.java +++ b/src/main/java/org/rostislav/quickdrop/controller/FileViewController.java @@ -44,7 +44,7 @@ public class FileViewController { @GetMapping("/list") public String listFiles(Model model) { - List files = fileService.getFiles(); + List files = fileService.getNotHiddenFiles(); model.addAttribute("files", files); return "listFiles"; } @@ -129,32 +129,54 @@ public class FileViewController { @GetMapping("/search") public String searchFiles(String query, Model model) { - List files = fileService.searchFiles(query); + List files = fileService.searchNotHiddenFiles(query); model.addAttribute("files", files); return "listFiles"; } @PostMapping("/keep-indefinitely/{id}") public String updateKeepIndefinitely(@PathVariable Long id, @RequestParam(required = false, defaultValue = "false") boolean keepIndefinitely, HttpServletRequest request, Model model) { + return handlePasswordValidationAndRedirect(id, request, model, () -> fileService.updateKeepIndefinitely(id, keepIndefinitely)); + } + + + @PostMapping("/toggle-hidden/{id}") + public String toggleHidden(@PathVariable Long id, HttpServletRequest request, Model model) { + return handlePasswordValidationAndRedirect(id, request, model, () -> fileService.toggleHidden(id)); + } + + + private String handlePasswordValidationAndRedirect(Long fileId, HttpServletRequest request, Model model, Runnable action) { + String referer = request.getHeader("Referer"); + // Check for admin password - if (!applicationSettingsService.checkForAdminPassword(request)) { - // Check for file password - String filePassword = (String) request.getSession().getAttribute("password"); - if (filePassword != null) { - FileEntity fileEntity = fileService.getFile(id); - // Check if file password is correct - if (fileEntity.passwordHash != null && !fileService.checkPassword(fileEntity.uuid, filePassword)) { - model.addAttribute("uuid", fileEntity.uuid); - return "file-password"; - } - // Redirect to file page - fileService.updateKeepIndefinitely(id, keepIndefinitely); - return "redirect:/file/" + fileEntity.uuid; - } - return "redirect:/admin/password"; + if (applicationSettingsService.checkForAdminPassword(request)) { + action.run(); + return "redirect:" + referer; } - fileService.updateKeepIndefinitely(id, keepIndefinitely); - return "redirect:/admin/dashboard"; + // Check for file password in the session + String filePassword = (String) request.getSession().getAttribute("password"); + if (filePassword != null) { + FileEntity fileEntity = fileService.getFile(fileId); + // Validate file password if the file is password-protected + if (fileEntity.passwordHash != null && !fileService.checkPassword(fileEntity.uuid, filePassword)) { + model.addAttribute("uuid", fileEntity.uuid); + return "file-password"; // Redirect to file password page if the password is incorrect + } + + action.run(); + return "redirect:" + referer; + } + + // No valid password found, determine the redirect destination + if (referer != null && referer.contains("/admin/dashboard")) { + return "redirect:/admin/password"; // Redirect to admin password page + } else { + // Get the file for adding the UUID to the model for the file password page + FileEntity fileEntity = fileService.getFile(fileId); + model.addAttribute("uuid", fileEntity.uuid); + return "file-password"; + } } } diff --git a/src/main/java/org/rostislav/quickdrop/entity/FileEntity.java b/src/main/java/org/rostislav/quickdrop/entity/FileEntity.java index e59d7b6..2c55bbb 100644 --- a/src/main/java/org/rostislav/quickdrop/entity/FileEntity.java +++ b/src/main/java/org/rostislav/quickdrop/entity/FileEntity.java @@ -17,6 +17,8 @@ public class FileEntity { public boolean keepIndefinitely; public LocalDate uploadDate; public String passwordHash; + @Column(columnDefinition = "boolean default false") + public boolean hidden; @PrePersist public void prePersist() { diff --git a/src/main/java/org/rostislav/quickdrop/model/FileEntityView.java b/src/main/java/org/rostislav/quickdrop/model/FileEntityView.java index 5c3f46c..ad689a0 100644 --- a/src/main/java/org/rostislav/quickdrop/model/FileEntityView.java +++ b/src/main/java/org/rostislav/quickdrop/model/FileEntityView.java @@ -13,6 +13,7 @@ public class FileEntityView { public boolean keepIndefinitely; public LocalDate uploadDate; public long totalDownloads; + public boolean hidden; public FileEntityView() { } @@ -26,5 +27,6 @@ public class FileEntityView { this.keepIndefinitely = fileEntity.keepIndefinitely; this.uploadDate = fileEntity.uploadDate; this.totalDownloads = totalDownloads; + this.hidden = fileEntity.hidden; } } diff --git a/src/main/java/org/rostislav/quickdrop/repository/FileRepository.java b/src/main/java/org/rostislav/quickdrop/repository/FileRepository.java index 6795bcc..8f8aa9e 100644 --- a/src/main/java/org/rostislav/quickdrop/repository/FileRepository.java +++ b/src/main/java/org/rostislav/quickdrop/repository/FileRepository.java @@ -16,9 +16,15 @@ public interface FileRepository extends JpaRepository { @Query("SELECT f FROM FileEntity f WHERE f.keepIndefinitely = false AND f.uploadDate < :thresholdDate") List getFilesForDeletion(@Param("thresholdDate") LocalDate thresholdDate); - @Query("SELECT f FROM FileEntity f WHERE f.name LIKE %:searchString% OR f.description LIKE %:searchString% OR f.uuid LIKE %:searchString%") + @Query("SELECT f FROM FileEntity f WHERE (LOWER(f.name) LIKE LOWER(CONCAT('%', :searchString, '%')) OR LOWER(f.description) LIKE LOWER(CONCAT('%', :searchString, '%')) OR LOWER(f.uuid) LIKE LOWER(CONCAT('%', :searchString, '%')))") List searchFiles(@Param("searchString") String searchString); + @Query("SELECT f FROM FileEntity f WHERE f.hidden = false") + List findAllNotHiddenFiles(); + @Query("SELECT SUM(f.size) FROM FileEntity f") Long totalFileSizeForAllFiles(); + + @Query("SELECT f FROM FileEntity f WHERE f.hidden = false AND (LOWER(f.name) LIKE LOWER(CONCAT('%', :searchString, '%')) OR LOWER(f.description) LIKE LOWER(CONCAT('%', :searchString, '%')) OR LOWER(f.uuid) LIKE LOWER(CONCAT('%', :searchString, '%')))") + List searchNotHiddenFiles(@Param("searchString") String query); } diff --git a/src/main/java/org/rostislav/quickdrop/service/FileService.java b/src/main/java/org/rostislav/quickdrop/service/FileService.java index db6c184..5def7c1 100644 --- a/src/main/java/org/rostislav/quickdrop/service/FileService.java +++ b/src/main/java/org/rostislav/quickdrop/service/FileService.java @@ -267,6 +267,10 @@ public class FileService { return fileRepository.searchFiles(query); } + public List searchNotHiddenFiles(String query) { + return fileRepository.searchNotHiddenFiles(query); + } + public long calculateTotalSpaceUsed() { return nullToZero(fileRepository.totalFileSizeForAllFiles()); } @@ -286,4 +290,20 @@ public class FileService { logger.info("File keepIndefinitely updated: {}", fileEntity); fileRepository.save(fileEntity); } + + public void toggleHidden(Long id) { + Optional referenceById = fileRepository.findById(id); + if (referenceById.isEmpty()) { + return; + } + + FileEntity fileEntity = referenceById.get(); + fileEntity.hidden = !fileEntity.hidden; + logger.info("File hidden updated: {}", fileEntity); + fileRepository.save(fileEntity); + } + + public List getNotHiddenFiles() { + return fileRepository.findAllNotHiddenFiles(); + } } diff --git a/src/main/resources/static/js/upload.js b/src/main/resources/static/js/upload.js index 906b8b9..1dc8338 100644 --- a/src/main/resources/static/js/upload.js +++ b/src/main/resources/static/js/upload.js @@ -117,4 +117,15 @@ function parseSize(size) { const value = parseFloat(valueMatch[0]); return value * (units[unit] || 1); +} + +function updateHiddenState(event, checkbox) { + event.preventDefault(); + const hiddenField = checkbox.form.querySelector('input[name="hidden"][type="hidden"]'); + if (hiddenField) { + hiddenField.value = checkbox.checked; + } + + console.log('Submitting hidden state form...'); + checkbox.form.submit(); } \ No newline at end of file diff --git a/src/main/resources/templates/admin/dashboard.html b/src/main/resources/templates/admin/dashboard.html index 7f834d5..1a6ba6e 100644 --- a/src/main/resources/templates/admin/dashboard.html +++ b/src/main/resources/templates/admin/dashboard.html @@ -63,53 +63,64 @@ - - - - - + + + + + + + - - - - - + + + + + + - - - + @@ -132,6 +143,20 @@ } + + + diff --git a/src/main/resources/templates/fileView.html b/src/main/resources/templates/fileView.html index 795dbbc..2f5e981 100644 --- a/src/main/resources/templates/fileView.html +++ b/src/main/resources/templates/fileView.html @@ -96,8 +96,25 @@ +
+
Hide File From List:
+
+ + +
+ +
+ +
-
+
File Size:
NameUpload DateSizeDownloadsActionsNameUpload DateSizeDownloadsKeep IndefinitelyHiddenActions
- +
-
- Keep Indefinitely -
- -
+
+
- - View File - - View - History + + +
+ + +
+ +
+
+
+ View File + History + Download - -
- +