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>
|
||||
|
||||
Reference in New Issue
Block a user