FEAT : Pagination des commentaires / photos
This commit is contained in:
@@ -51,7 +51,7 @@ public class PhotoController {
|
||||
|
||||
@PostMapping("/upload")
|
||||
public String doUpload(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(value="visibilite", defaultValue = "PRIVATE") String visibilite,
|
||||
@RequestParam(value = "visibilite", defaultValue = "PRIVATE") String visibilite,
|
||||
Authentication authentication,
|
||||
Model model) {
|
||||
try {
|
||||
@@ -82,7 +82,8 @@ public class PhotoController {
|
||||
String contentType = "application/octet-stream";
|
||||
try {
|
||||
contentType = Files.probeContentType(p);
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType(contentType))
|
||||
@@ -92,14 +93,27 @@ public class PhotoController {
|
||||
}
|
||||
|
||||
@GetMapping("/mes-photos")
|
||||
public String mesPhotos(Model model, Authentication auth) {
|
||||
public String mesPhotos(
|
||||
@RequestParam(name = "pagePrivees", defaultValue = "0") int pagePrivees,
|
||||
@RequestParam(name = "pagePubliques", defaultValue = "0") int pagePubliques,
|
||||
@RequestParam(name = "pagePartagees", defaultValue = "0") int pagePartagees,
|
||||
Model model,
|
||||
Authentication auth
|
||||
) {
|
||||
String email = auth.getName();
|
||||
model.addAttribute("photosPrivees", photoService.listPrivatePhotos(email));
|
||||
model.addAttribute("photosPubliques", photoService.listPublicPhotos(email));
|
||||
model.addAttribute("photosPartagees", photoService.listSharedWith(email));
|
||||
// Chaque liste utilise sa propre pagination
|
||||
model.addAttribute("photosPrivees", photoService.listPrivatePhotos(email, pagePrivees, 12));
|
||||
model.addAttribute("photosPubliques", photoService.listPublicPhotos(email, pagePubliques, 12));
|
||||
model.addAttribute("photosPartagees", photoService.listSharedWith(email, pagePartagees, 12));
|
||||
|
||||
// Ajouter les 3 index séparés
|
||||
model.addAttribute("pagePrivees", pagePrivees);
|
||||
model.addAttribute("pagePubliques", pagePubliques);
|
||||
model.addAttribute("pagePartagees", pagePartagees);
|
||||
return "mes-photos";
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/galerie")
|
||||
public String galerie(@RequestParam(defaultValue = "0") int page, Model model) {
|
||||
Page<Photo> photosPage = photoService.listPublic(page, 12);
|
||||
@@ -112,28 +126,28 @@ public class PhotoController {
|
||||
@GetMapping("/photo/{id}")
|
||||
@PreAuthorize("@securityService.canAccessPhoto(authentication, #id)")
|
||||
public String viewPhoto(@PathVariable Long id,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
Model model,
|
||||
Authentication auth) {
|
||||
|
||||
Photo photo = photoRepository.findById(id).orElse(null);
|
||||
if (photo == null) {
|
||||
return "redirect:/galerie";
|
||||
}
|
||||
|
||||
model.addAttribute("photo", photo);
|
||||
model.addAttribute("commentaires", commentaireService.listByPhoto(id));
|
||||
|
||||
// utilisateur connecté (peut être null si visiteur)
|
||||
// Pagination des commentaires
|
||||
model.addAttribute("commentairesPage",
|
||||
commentaireService.listByPhoto(id, page, 10));
|
||||
model.addAttribute("currentPage", page);
|
||||
// utilisateur connecté (peut être null)
|
||||
String currentUser = (auth != null ? auth.getName() : null);
|
||||
model.addAttribute("currentUser", currentUser);
|
||||
|
||||
// Liste des partages
|
||||
List<Partage> partages = partageRepository.findByPhoto_Id(id);
|
||||
model.addAttribute("partages", partages);
|
||||
|
||||
return "photo-detail";
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/photo/{id}/comment")
|
||||
public String addComment(@PathVariable Long id,
|
||||
@RequestParam String contenu,
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package local.epul4a.fotosharing.repository;
|
||||
|
||||
import local.epul4a.fotosharing.model.Commentaire;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
|
||||
public interface CommentaireRepository extends JpaRepository<Commentaire, Long> {
|
||||
|
||||
List<Commentaire> findByPhoto_IdOrderByDateCommentaireAsc(Long photoId);
|
||||
Page<Commentaire> findByPhoto_Id(Long photoId, Pageable pageable);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,5 +11,16 @@ public interface PhotoRepository extends JpaRepository<Photo, Long> {
|
||||
List<Photo> findByProprietaire_Email(String email);
|
||||
List<Photo> findByVisibilite(Photo.Visibilite visibilite);
|
||||
Page<Photo> findByVisibilite(Photo.Visibilite visibilite, Pageable pageable);
|
||||
Page<Photo> findByProprietaire_Email(String email, Pageable pageable);
|
||||
Page<Photo> findByProprietaire_EmailAndVisibilite(
|
||||
String email,
|
||||
Photo.Visibilite visibilite,
|
||||
Pageable pageable
|
||||
);
|
||||
|
||||
Page<Photo> findByVisibiliteAndProprietaire_Email(
|
||||
Photo.Visibilite visibilite,
|
||||
String email,
|
||||
Pageable pageable
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package local.epul4a.fotosharing.service;
|
||||
|
||||
import local.epul4a.fotosharing.model.Commentaire;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CommentaireService {
|
||||
List<Commentaire> listByPhoto(Long photoId);
|
||||
void addComment(Long photoId, String email, String contenu);
|
||||
Page<Commentaire> listByPhoto(Long photoId, int page, int size);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ public interface PhotoService {
|
||||
List<Photo> listPublicPhotos(String email);
|
||||
void unshare(Long photoId, String email);
|
||||
Page<Photo> listPublic(int page, int size);
|
||||
Page<Photo> listPrivatePhotos(String email, int page, int size);
|
||||
Page<Photo> listPublicPhotos(String email, int page, int size);
|
||||
Page<Photo> listSharedWith(String email, int page, int size);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ import local.epul4a.fotosharing.repository.CommentaireRepository;
|
||||
import local.epul4a.fotosharing.repository.PhotoRepository;
|
||||
import local.epul4a.fotosharing.repository.UtilisateurRepository;
|
||||
import local.epul4a.fotosharing.service.CommentaireService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -47,4 +50,10 @@ public class CommentaireServiceImpl implements CommentaireService {
|
||||
|
||||
commentaireRepository.save(c);
|
||||
}
|
||||
@Override
|
||||
public Page<Commentaire> listByPhoto(Long photoId, int page, int size) {
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
return commentaireRepository.findByPhoto_Id(photoId, pageable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import local.epul4a.fotosharing.repository.UtilisateurRepository;
|
||||
import local.epul4a.fotosharing.service.PhotoService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -115,5 +116,35 @@ public class PhotoServiceImpl implements PhotoService {
|
||||
return photoRepository.findByVisibilite(Photo.Visibilite.PUBLIC, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Photo> listPrivatePhotos(String email, int page, int size) {
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
return photoRepository.findByProprietaire_EmailAndVisibilite(
|
||||
email,
|
||||
Photo.Visibilite.PRIVATE,
|
||||
pageable
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Photo> listPublicPhotos(String email, int page, int size) {
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
return photoRepository.findByProprietaire_EmailAndVisibilite(
|
||||
email,
|
||||
Photo.Visibilite.PUBLIC,
|
||||
pageable
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Photo> listSharedWith(String email, int page, int size) {
|
||||
List<Partage> partages = partageRepository.findByUtilisateur_Email(email);
|
||||
List<Photo> photos = partages.stream().map(Partage::getPhoto).toList();
|
||||
// convertir list en page manuellement
|
||||
int start = page * size;
|
||||
int end = Math.min(start + size, photos.size());
|
||||
List<Photo> sublist = photos.subList(start, end);
|
||||
return new PageImpl<>(sublist, PageRequest.of(page, size), photos.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,31 +12,51 @@
|
||||
<p>Vous n'avez pas encore de photos.</p>
|
||||
</div>
|
||||
<h2>Mes photos privées</h2>
|
||||
<ul>
|
||||
<li th:each="p : ${photosPrivees}">
|
||||
<a th:href="@{'/photo/' + ${p.id}}"
|
||||
th:text="${p.nomFichierOriginal}"></a>
|
||||
<span style="color:red;">[PRIVÉE]</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<a th:each="p : ${photosPrivees.content}"
|
||||
th:href="@{'/photo/' + ${p.id}}">
|
||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a th:if="${photosPrivees.hasPrevious()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees - 1}, pagePubliques=${pagePubliques}, pagePartagees=${pagePartagees})}">⬅</a>
|
||||
<span th:text="'Page ' + (${pagePrivees}+1)"></span>
|
||||
<a th:if="${photosPrivees.hasNext()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees + 1}, pagePubliques=${pagePubliques}, pagePartagees=${pagePartagees})}">➡</a>
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Mes photos publiques</h2>
|
||||
<ul>
|
||||
<li th:each="p : ${photosPubliques}">
|
||||
<a th:href="@{'/photo/' + ${p.id}}"
|
||||
th:text="${p.nomFichierOriginal}"></a>
|
||||
<span style="color:blue;">[PUBLIQUE]</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<a th:each="p : ${photosPubliques.content}"
|
||||
th:href="@{'/photo/' + ${p.id}}">
|
||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a th:if="${photosPubliques.hasPrevious()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees}, pagePubliques=${pagePubliques - 1}, pagePartagees=${pagePartagees})}">⬅</a>
|
||||
<span th:text="'Page ' + (${pagePubliques}+1)"></span>
|
||||
<a th:if="${photosPubliques.hasNext()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees}, pagePubliques=${pagePubliques + 1}, pagePartagees=${pagePartagees})}">➡</a>
|
||||
|
||||
</div>
|
||||
|
||||
<h2>Photos partagées avec moi</h2>
|
||||
<ul>
|
||||
<li th:each="p : ${photosPartagees}">
|
||||
<a th:href="@{'/photo/' + ${p.id}}"
|
||||
th:text="${p.nomFichierOriginal}"></a>
|
||||
<span style="color:green;">[SHARED]</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<a th:each="p : ${photosPartagees.content}"
|
||||
th:href="@{'/photo/' + ${p.id}}">
|
||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a th:if="${photosPartagees.hasPrevious()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees}, pagePubliques=${pagePubliques}, pagePartagees=${pagePartagees - 1})}">⬅</a>
|
||||
<span th:text="'Page ' + (${pagePartagees}+1)"></span>
|
||||
<a th:if="${photosPartagees.hasNext()}"
|
||||
th:href="@{/mes-photos(pagePrivees=${pagePrivees}, pagePubliques=${pagePubliques}, pagePartagees=${pagePartagees + 1})}">➡</a>
|
||||
</div>
|
||||
|
||||
|
||||
<p><a th:href="@{/galerie}">Galerie publique</a></p>
|
||||
|
||||
@@ -53,16 +53,20 @@
|
||||
|
||||
<!-- Commentaires -->
|
||||
<h2>Commentaires</h2>
|
||||
<div th:if="${#lists.isEmpty(commentaires)}">
|
||||
<p>Aucun commentaire pour l'instant.</p>
|
||||
</div>
|
||||
<ul th:if="${!#lists.isEmpty(commentaires)}">
|
||||
<li th:each="c : ${commentaires}">
|
||||
<strong th:text="${c.auteur.email}">Auteur</strong> :
|
||||
<div th:each="c : ${commentairesPage.content}">
|
||||
<p>
|
||||
<b th:text="${c.auteur.email}"></b>
|
||||
<span th:text="${c.contenu}"></span>
|
||||
<em>(<span th:text="${c.dateCommentaire}"></span>)</em>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<a th:if="${commentairesPage.hasPrevious()}"
|
||||
th:href="@{/photo/{id}(id=${photo.id}, page=${currentPage - 1})}">⬅</a>
|
||||
<span th:text="'Page ' + (${currentPage}+1)"></span>
|
||||
<a th:if="${commentairesPage.hasNext()}"
|
||||
th:href="@{/photo/{id}(id=${photo.id}, page=${currentPage + 1})}">➡</a>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire d'ajout de commentaire -->
|
||||
<div th:if="${currentUser}">
|
||||
<h3>Ajouter un commentaire</h3>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,17 +0,0 @@
|
||||
spring.application.name=FotoSharing
|
||||
|
||||
# ===============================
|
||||
# DATABASE
|
||||
# ===============================
|
||||
spring.datasource.url=jdbc:mariadb://192.168.124.171:3306/fotoshareDB
|
||||
spring.datasource.username=ufoto
|
||||
spring.datasource.password=4AinfoRep-25
|
||||
# ===============================
|
||||
# JPA / HIBERNATE
|
||||
# ===============================
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
|
||||
spring.jpa.show-sql=true
|
||||
spring.thymeleaf.prefix=classpath:/templates/
|
||||
spring.thymeleaf.suffix=.html
|
||||
spring.thymeleaf.mode=HTML
|
||||
Binary file not shown.
@@ -1,9 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>FotoSharing Title!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>FotoSharing Title!</h1>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
|
||||
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0"
|
||||
metadata-complete="false">
|
||||
|
||||
<display-name>FotoSharing</display-name>
|
||||
|
||||
<!-- Désactiver l'enregistrement automatique du filtre d'erreur -->
|
||||
<absolute-ordering>
|
||||
<name>spring_web</name>
|
||||
</absolute-ordering>
|
||||
|
||||
</web-app>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
spring.application.name=FotoSharing
|
||||
spring.jmx.enabled=false
|
||||
management.endpoints.jmx.exposure.exclude=*
|
||||
|
||||
|
||||
# ===============================
|
||||
# DATABASE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user