FEAT : Ajout du mécanisme d'album avec partage et visibilité
This commit is contained in:
@@ -0,0 +1,169 @@
|
|||||||
|
package local.epul4a.fotosharing.controller;
|
||||||
|
|
||||||
|
import local.epul4a.fotosharing.dto.AlbumDTO;
|
||||||
|
import local.epul4a.fotosharing.dto.PhotoDTO;
|
||||||
|
import local.epul4a.fotosharing.service.AlbumService;
|
||||||
|
import local.epul4a.fotosharing.service.PartageService;
|
||||||
|
import local.epul4a.fotosharing.service.PhotoService;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class AlbumController {
|
||||||
|
|
||||||
|
private final AlbumService albumService;
|
||||||
|
private final PhotoService photoService;
|
||||||
|
private final PartageService partageService;
|
||||||
|
public AlbumController(AlbumService albumService,PhotoService photoService,PartageService partageService) {
|
||||||
|
this.albumService = albumService;
|
||||||
|
this.photoService = photoService;
|
||||||
|
this.partageService = partageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ MES ALBUMS ============================ */
|
||||||
|
@GetMapping("/mes-albums")
|
||||||
|
public String mesAlbums(
|
||||||
|
@RequestParam(defaultValue = "0") int page,
|
||||||
|
Authentication auth,
|
||||||
|
Model model
|
||||||
|
) {
|
||||||
|
String email = auth.getName();
|
||||||
|
Page<AlbumDTO> albums = albumService.listMyAlbums(email, page, 10);
|
||||||
|
List<AlbumDTO> sharedAlbums = albumService.listAlbumsSharedWithMe(email);
|
||||||
|
model.addAttribute("albums", albums);
|
||||||
|
model.addAttribute("currentPage", page);
|
||||||
|
model.addAttribute("sharedAlbums", sharedAlbums);
|
||||||
|
return "mes-albums";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================ CREATION ALBUM ============================ */
|
||||||
|
@PostMapping("/albums/create")
|
||||||
|
public String createAlbum(
|
||||||
|
@RequestParam String nom,
|
||||||
|
@RequestParam(required = false) String description,
|
||||||
|
@RequestParam(defaultValue = "PRIVATE") String visibilite,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.createAlbum(nom, description, visibilite, auth.getName());
|
||||||
|
return "redirect:/mes-albums";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================ DETAIL ALBUM ============================ */
|
||||||
|
@GetMapping("/album/{id}")
|
||||||
|
public String viewAlbum(
|
||||||
|
@PathVariable Long id,
|
||||||
|
Authentication auth,
|
||||||
|
Model model
|
||||||
|
) {
|
||||||
|
String email = auth.getName();
|
||||||
|
AlbumDTO album = albumService.getAlbum(id);
|
||||||
|
if (album == null)
|
||||||
|
return "redirect:/mes-albums";
|
||||||
|
model.addAttribute("album", album);
|
||||||
|
model.addAttribute("myPhotos", photoService.listAllPhotosOfUser(email));
|
||||||
|
model.addAttribute("partages", partageService.getAlbumPartages(id));
|
||||||
|
boolean canAdmin = partageService.canAdminAlbum(id, email);
|
||||||
|
model.addAttribute("canAdmin", canAdmin);
|
||||||
|
return "album-detail";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================ AJOUT PHOTO ============================ */
|
||||||
|
@PostMapping("/album/{id}/add")
|
||||||
|
public String addPhoto(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@RequestParam Long photoId,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
albumService.addPhoto(id, photoId, auth.getName());
|
||||||
|
return "redirect:/album/" + id + "?added=ok";
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
return "redirect:/album/" + id + "?error=" + URLEncoder.encode(ex.getMessage(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================ RETIRER PHOTO ============================ */
|
||||||
|
@GetMapping("/album/{id}/remove/{photoId}")
|
||||||
|
public String removePhoto(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@PathVariable Long photoId,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.removePhoto(id, photoId, auth.getName());
|
||||||
|
return "redirect:/album/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ SUPPRESSION ALBUM ============================ */
|
||||||
|
@GetMapping("/album/{id}/delete")
|
||||||
|
public String deleteAlbum(
|
||||||
|
@PathVariable Long id,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.deleteAlbum(id, auth.getName());
|
||||||
|
return "redirect:/mes-albums";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ PARTAGE ALBUM ============================ */
|
||||||
|
@PostMapping("/album/{id}/share")
|
||||||
|
public String shareAlbum(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@RequestParam String email,
|
||||||
|
@RequestParam String permission,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
albumService.shareAlbum(id, email, permission, auth.getName());
|
||||||
|
return "redirect:/album/" + id + "?shared=ok";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "redirect:/album/" + id + "?error=" + e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================ SUPPRIMER PARTAGE ALBUM ============================ */
|
||||||
|
@GetMapping("/album/{id}/share/remove/{email}")
|
||||||
|
public String removeShareAlbum(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@PathVariable String email,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.removeAlbumShare(id, email, auth.getName());
|
||||||
|
return "redirect:/album/" + id + "?removed=ok";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ MAJ PARTAGE ALBUM ============================ */
|
||||||
|
@PostMapping("/album/{id}/share/update")
|
||||||
|
public String updateAlbumShare(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@RequestParam String email,
|
||||||
|
@RequestParam String permission,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.updateAlbumPermission(id, email, permission, auth.getName());
|
||||||
|
return "redirect:/album/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================ SUPPRIMER PARTAGE ALBUM ============================ */
|
||||||
|
@GetMapping("/album/{id}/unshare/{email}")
|
||||||
|
public String unshareAlbum(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@PathVariable String email,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
albumService.removeAlbumShare(id, email, auth.getName());
|
||||||
|
return "redirect:/album/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
20
src/main/java/local/epul4a/fotosharing/dto/AlbumDTO.java
Normal file
20
src/main/java/local/epul4a/fotosharing/dto/AlbumDTO.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package local.epul4a.fotosharing.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AlbumDTO {
|
||||||
|
private Long id;
|
||||||
|
private String nom;
|
||||||
|
private String description;
|
||||||
|
private String visibilite;
|
||||||
|
private LocalDateTime dateCreation;
|
||||||
|
private UtilisateurDTO proprietaire;
|
||||||
|
// Liste des photos pas les IDs pour éviter les boucles
|
||||||
|
private List<PhotoDTO> photos;
|
||||||
|
}
|
||||||
@@ -10,4 +10,8 @@ public class PartageDTO {
|
|||||||
private UtilisateurDTO utilisateur;
|
private UtilisateurDTO utilisateur;
|
||||||
private String permission; // READ / COMMENT / ADMIN
|
private String permission; // READ / COMMENT / ADMIN
|
||||||
private PhotoDTO photo;
|
private PhotoDTO photo;
|
||||||
|
|
||||||
|
public String getUtilisateurEmail() {
|
||||||
|
return utilisateur != null ? utilisateur.getEmail() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package local.epul4a.fotosharing.mapper;
|
||||||
|
|
||||||
|
import local.epul4a.fotosharing.dto.AlbumDTO;
|
||||||
|
import local.epul4a.fotosharing.dto.PhotoDTO;
|
||||||
|
import local.epul4a.fotosharing.model.Album;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class AlbumMapper {
|
||||||
|
public static AlbumDTO toDTO(Album album) {
|
||||||
|
if (album == null) return null;
|
||||||
|
AlbumDTO dto = new AlbumDTO();
|
||||||
|
dto.setId(album.getId());
|
||||||
|
dto.setNom(album.getNom());
|
||||||
|
dto.setDescription(album.getDescription());
|
||||||
|
dto.setVisibilite(album.getVisibilite().name());
|
||||||
|
dto.setDateCreation(album.getDateCreation());
|
||||||
|
dto.setProprietaire(UtilisateurMapper.toDTO(album.getProprietaire()));
|
||||||
|
dto.setPhotos(
|
||||||
|
album.getPhotos()
|
||||||
|
.stream()
|
||||||
|
.map(PhotoMapper::toDTO)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/main/java/local/epul4a/fotosharing/model/Album.java
Normal file
52
src/main/java/local/epul4a/fotosharing/model/Album.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package local.epul4a.fotosharing.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Album {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String nom;
|
||||||
|
|
||||||
|
@Column(length = 1000)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
private Utilisateur proprietaire;
|
||||||
|
|
||||||
|
private LocalDateTime dateCreation;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Visibilite visibilite;
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(
|
||||||
|
name = "album_photo",
|
||||||
|
joinColumns = @JoinColumn(name = "album_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "photo_id")
|
||||||
|
)
|
||||||
|
private Set<Photo> photos = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
private Set<Partage> partages = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
public enum Visibilite {
|
||||||
|
PRIVATE,
|
||||||
|
SHARED,
|
||||||
|
PUBLIC
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,25 +8,25 @@ import lombok.Setter;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class Partage {
|
public class Partage {
|
||||||
public enum Permission {
|
|
||||||
READ,
|
|
||||||
COMMENT,
|
|
||||||
ADMIN
|
|
||||||
}
|
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "id_photo")
|
|
||||||
private Photo photo;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
@JoinColumn(name = "id_utilisateur")
|
|
||||||
private Utilisateur utilisateur;
|
private Utilisateur utilisateur;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private Permission permission = Permission.READ;
|
private Permission permission;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Photo photo; // nullable si partage d’album
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Album album; // nullable si partage de photo
|
||||||
|
|
||||||
|
public enum Permission {
|
||||||
|
READ, COMMENT, ADMIN
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
@@ -28,5 +29,9 @@ public class Photo {
|
|||||||
@JoinColumn(name = "id_utilisateur")
|
@JoinColumn(name = "id_utilisateur")
|
||||||
private Utilisateur proprietaire;
|
private Utilisateur proprietaire;
|
||||||
|
|
||||||
// getters & setters
|
@ManyToMany(mappedBy = "photos")
|
||||||
|
private Set<Album> albums = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "photo", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
private Set<Partage> partages = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package local.epul4a.fotosharing.repository;
|
||||||
|
|
||||||
|
import local.epul4a.fotosharing.model.Album;
|
||||||
|
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 AlbumRepository extends JpaRepository<Album, Long> {
|
||||||
|
// Albums dont je suis propriétaire
|
||||||
|
List<Album> findByProprietaire_Email(String email);
|
||||||
|
Page<Album> findByProprietaire_Email(String email, Pageable pageable);
|
||||||
|
// Albums publics
|
||||||
|
Page<Album> findByVisibilite(Album.Visibilite visibilite, Pageable pageable);
|
||||||
|
List<Album> findByPartages_Utilisateur_Email(String email);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,10 +7,16 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface PartageRepository extends JpaRepository<Partage, Long> {
|
public interface PartageRepository extends JpaRepository<Partage, Long> {
|
||||||
|
// PHOTO
|
||||||
List<Partage> findByPhoto_Id(Long photoId);
|
List<Partage> findByPhoto_Id(Long photoId);
|
||||||
boolean existsByPhoto_IdAndUtilisateur_Email(Long photoId, String email);
|
boolean existsByPhoto_IdAndUtilisateur_Email(Long photoId, String email);
|
||||||
|
Partage findByPhoto_IdAndUtilisateur_Email(Long photoId, String email);
|
||||||
|
// ALBUM
|
||||||
|
List<Partage> findByAlbum_Id(Long albumId);
|
||||||
|
boolean existsByAlbum_IdAndUtilisateur_Email(Long albumId, String email);
|
||||||
|
Partage findByAlbum_IdAndUtilisateur_Email(Long albumId, String email);
|
||||||
List<Partage> findByUtilisateur_Email(String email);
|
List<Partage> findByUtilisateur_Email(String email);
|
||||||
Optional<Partage> findByPhoto_IdAndUtilisateur_Email(Long photoId, String email);
|
|
||||||
int countByPhoto_Id(Long photoId);
|
int countByPhoto_Id(Long photoId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package local.epul4a.fotosharing.service;
|
||||||
|
|
||||||
|
import local.epul4a.fotosharing.dto.AlbumDTO;
|
||||||
|
import local.epul4a.fotosharing.dto.PartageDTO;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AlbumService {
|
||||||
|
AlbumDTO createAlbum(String nom, String description, String visibilite, String ownerEmail);
|
||||||
|
Page<AlbumDTO> listMyAlbums(String email, int page, int size);
|
||||||
|
Page<AlbumDTO> listPublicAlbums(int page, int size);
|
||||||
|
AlbumDTO getAlbum(Long id);
|
||||||
|
void addPhoto(Long albumId, Long photoId, String ownerEmail);
|
||||||
|
void removePhoto(Long albumId, Long photoId, String ownerEmail);
|
||||||
|
void deleteAlbum(Long albumId, String ownerEmail);
|
||||||
|
void shareAlbum(Long albumId, String targetEmail, String permission, String ownerEmail);
|
||||||
|
void updateAlbumPermission(Long albumId, String targetEmail, String permission, String ownerEmail);
|
||||||
|
void removeAlbumShare(Long albumId, String targetEmail, String ownerEmail);
|
||||||
|
List<PartageDTO> getAlbumPartages(Long albumId);
|
||||||
|
List<AlbumDTO> listAlbumsSharedWithMe(String email);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,5 +15,13 @@ public interface PartageService {
|
|||||||
boolean canAdmin(Long photoId, String email);
|
boolean canAdmin(Long photoId, String email);
|
||||||
void updatePermission(Long photoId, String targetEmail, String newPermission, String ownerEmail);
|
void updatePermission(Long photoId, String targetEmail, String newPermission, String ownerEmail);
|
||||||
int countShares(Long photoId);
|
int countShares(Long photoId);
|
||||||
|
void shareAlbum(Long albumId, String targetEmail, String permission, String ownerEmail);
|
||||||
|
void updateAlbumPermission(Long albumId, String targetEmail, String newPermission, String ownerEmail);
|
||||||
|
boolean canViewAlbum(Long albumId, String email);
|
||||||
|
boolean canCommentAlbum(Long albumId, String email);
|
||||||
|
boolean canAdminAlbum(Long albumId, String email);
|
||||||
|
List<PartageDTO> getAlbumPartages(Long albumId);
|
||||||
|
void removeAlbumShare(Long albumId, String targetEmail, String ownerEmail);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public interface PhotoService {
|
|||||||
Page<PhotoDTO> listPublicPhotos(String email, int page, int size);
|
Page<PhotoDTO> listPublicPhotos(String email, int page, int size);
|
||||||
Page<PhotoDTO> listSharedWith(String email, int page, int size);
|
Page<PhotoDTO> listSharedWith(String email, int page, int size);
|
||||||
Page<PhotoDTO> listSharedPhotos(String email, int page, int size);
|
Page<PhotoDTO> listSharedPhotos(String email, int page, int size);
|
||||||
|
List<PhotoDTO> listAllPhotosOfUser(String email);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
package local.epul4a.fotosharing.service.impl;
|
||||||
|
|
||||||
|
import local.epul4a.fotosharing.dto.AlbumDTO;
|
||||||
|
import local.epul4a.fotosharing.mapper.AlbumMapper;
|
||||||
|
import local.epul4a.fotosharing.model.Album;
|
||||||
|
import local.epul4a.fotosharing.model.Partage;
|
||||||
|
import local.epul4a.fotosharing.model.Photo;
|
||||||
|
import local.epul4a.fotosharing.model.Utilisateur;
|
||||||
|
import local.epul4a.fotosharing.repository.AlbumRepository;
|
||||||
|
import local.epul4a.fotosharing.repository.PartageRepository;
|
||||||
|
import local.epul4a.fotosharing.repository.PhotoRepository;
|
||||||
|
import local.epul4a.fotosharing.repository.UtilisateurRepository;
|
||||||
|
import local.epul4a.fotosharing.service.AlbumService;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import local.epul4a.fotosharing.service.PartageService;
|
||||||
|
import local.epul4a.fotosharing.dto.PartageDTO;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AlbumServiceImpl implements AlbumService {
|
||||||
|
private final AlbumRepository albumRepository;
|
||||||
|
private final UtilisateurRepository utilisateurRepository;
|
||||||
|
private final PhotoRepository photoRepository;
|
||||||
|
private final PartageService partageService;
|
||||||
|
private final PartageRepository partageRepository;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public AlbumServiceImpl(
|
||||||
|
AlbumRepository albumRepository,
|
||||||
|
UtilisateurRepository utilisateurRepository,
|
||||||
|
PhotoRepository photoRepository,
|
||||||
|
PartageService partageService,
|
||||||
|
PartageRepository partageRepository
|
||||||
|
) {
|
||||||
|
this.albumRepository = albumRepository;
|
||||||
|
this.utilisateurRepository = utilisateurRepository;
|
||||||
|
this.photoRepository = photoRepository;
|
||||||
|
this.partageService = partageService;
|
||||||
|
this.partageRepository = partageRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AlbumDTO createAlbum(String nom, String description, String visibilite, String ownerEmail) {
|
||||||
|
Utilisateur user = utilisateurRepository.findByEmail(ownerEmail)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Utilisateur introuvable"));
|
||||||
|
Album album = new Album();
|
||||||
|
album.setNom(nom);
|
||||||
|
album.setDescription(description);
|
||||||
|
album.setVisibilite(Album.Visibilite.valueOf(visibilite));
|
||||||
|
album.setProprietaire(user);
|
||||||
|
album.setDateCreation(LocalDateTime.now());
|
||||||
|
return AlbumMapper.toDTO(albumRepository.save(album));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<AlbumDTO> listMyAlbums(String email, int page, int size) {
|
||||||
|
return albumRepository.findByProprietaire_Email(email, PageRequest.of(page, size))
|
||||||
|
.map(AlbumMapper::toDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<AlbumDTO> listPublicAlbums(int page, int size) {
|
||||||
|
return albumRepository.findByVisibilite(Album.Visibilite.PUBLIC, PageRequest.of(page, size))
|
||||||
|
.map(AlbumMapper::toDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AlbumDTO getAlbum(Long id) {
|
||||||
|
return albumRepository.findById(id)
|
||||||
|
.map(AlbumMapper::toDTO)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPhoto(Long albumId, Long photoId, String requesterEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
//Propriétaire
|
||||||
|
boolean isOwner = album.getProprietaire().getEmail().equals(requesterEmail);
|
||||||
|
//admin du partage
|
||||||
|
boolean isAdmin = album.getPartages().stream()
|
||||||
|
.anyMatch(p ->
|
||||||
|
p.getUtilisateur().getEmail().equals(requesterEmail)
|
||||||
|
&& p.getPermission() == Partage.Permission.ADMIN
|
||||||
|
);
|
||||||
|
if (!isOwner && !isAdmin)
|
||||||
|
throw new RuntimeException("Vous n’avez pas les droits pour modifier cet album");
|
||||||
|
Photo photo = photoRepository.findById(photoId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||||
|
//Protection anti-doublons
|
||||||
|
boolean exists = album.getPhotos()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(p -> p.getId().equals(photoId));
|
||||||
|
if (exists)
|
||||||
|
throw new RuntimeException("Cette photo est déjà dans cet album");
|
||||||
|
album.getPhotos().add(photo);
|
||||||
|
albumRepository.save(album);
|
||||||
|
// Synchroniser les partages sur la photo pour les utilisateurs de l'album
|
||||||
|
album.getPartages().forEach(p -> {
|
||||||
|
// On vérifie si l'utilisateur n'a PAS déjà un partage sur cette photo
|
||||||
|
boolean existeDeja = photo.getPartages().stream()
|
||||||
|
.anyMatch(pp -> pp.getUtilisateur().getEmail().equals(p.getUtilisateur().getEmail()));
|
||||||
|
|
||||||
|
if (!existeDeja) {
|
||||||
|
// On crée un partage photo identique à l'autorisation de l'album
|
||||||
|
partageService.share(photo.getId(), p.getUtilisateur().getEmail(), p.getPermission().name(), requesterEmail);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// S'assurer que le propriétaire a aussi accès
|
||||||
|
boolean ownerHasAccess = photo.getPartages().stream()
|
||||||
|
.anyMatch(p -> p.getUtilisateur().getEmail().equals(album.getProprietaire().getEmail()));
|
||||||
|
|
||||||
|
if (!ownerHasAccess) {
|
||||||
|
partageService.share(photo.getId(), album.getProprietaire().getEmail(), "ADMIN", requesterEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removePhoto(Long albumId, Long photoId, String ownerEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
if (!album.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
|
throw new RuntimeException("Vous n'êtes pas propriétaire de l’album");
|
||||||
|
Photo photo = photoRepository.findById(photoId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||||
|
album.getPhotos().remove(photo);
|
||||||
|
albumRepository.save(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAlbum(Long albumId, String ownerEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
if (!album.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
|
throw new RuntimeException("Vous n'êtes pas propriétaire de l’album");
|
||||||
|
albumRepository.delete(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shareAlbum(Long albumId, String targetEmail, String permission, String ownerEmail) {
|
||||||
|
partageService.shareAlbum(albumId, targetEmail, permission, ownerEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAlbumPermission(Long albumId, String targetEmail, String permission, String ownerEmail) {
|
||||||
|
partageService.updateAlbumPermission(albumId, targetEmail, permission, ownerEmail);
|
||||||
|
// --- Synchroniser les permissions sur toutes les photos de l’album ---
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
for (Photo photo : album.getPhotos()) {
|
||||||
|
// Chercher un partage photo existant
|
||||||
|
Partage partagePhoto = photo.getPartages().stream()
|
||||||
|
.filter(p -> p.getUtilisateur().getEmail().equals(targetEmail))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (partagePhoto != null) {
|
||||||
|
// Mettre à jour la permission
|
||||||
|
partagePhoto.setPermission(Partage.Permission.valueOf(permission));
|
||||||
|
partageRepository.save(partagePhoto);
|
||||||
|
} else {
|
||||||
|
// Si pas encore partagé → création
|
||||||
|
partageService.share(
|
||||||
|
photo.getId(),
|
||||||
|
targetEmail,
|
||||||
|
permission,
|
||||||
|
ownerEmail
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAlbumShare(Long albumId, String targetEmail, String ownerEmail) {
|
||||||
|
partageService.removeAlbumShare(albumId, targetEmail, ownerEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PartageDTO> getAlbumPartages(Long albumId) {
|
||||||
|
return partageService.getAlbumPartages(albumId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AlbumDTO> listAlbumsSharedWithMe(String email) {
|
||||||
|
return albumRepository.findByPartages_Utilisateur_Email(email)
|
||||||
|
.stream()
|
||||||
|
.filter(a -> !a.getProprietaire().getEmail().equals(email))
|
||||||
|
.map(AlbumMapper::toDTO)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,9 +2,11 @@ package local.epul4a.fotosharing.service.impl;
|
|||||||
|
|
||||||
import local.epul4a.fotosharing.dto.PartageDTO;
|
import local.epul4a.fotosharing.dto.PartageDTO;
|
||||||
import local.epul4a.fotosharing.mapper.PartageMapper;
|
import local.epul4a.fotosharing.mapper.PartageMapper;
|
||||||
|
import local.epul4a.fotosharing.model.Album;
|
||||||
import local.epul4a.fotosharing.model.Partage;
|
import local.epul4a.fotosharing.model.Partage;
|
||||||
import local.epul4a.fotosharing.model.Photo;
|
import local.epul4a.fotosharing.model.Photo;
|
||||||
import local.epul4a.fotosharing.model.Utilisateur;
|
import local.epul4a.fotosharing.model.Utilisateur;
|
||||||
|
import local.epul4a.fotosharing.repository.AlbumRepository;
|
||||||
import local.epul4a.fotosharing.repository.PartageRepository;
|
import local.epul4a.fotosharing.repository.PartageRepository;
|
||||||
import local.epul4a.fotosharing.repository.PhotoRepository;
|
import local.epul4a.fotosharing.repository.PhotoRepository;
|
||||||
import local.epul4a.fotosharing.repository.UtilisateurRepository;
|
import local.epul4a.fotosharing.repository.UtilisateurRepository;
|
||||||
@@ -19,15 +21,18 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
private final PartageRepository partageRepository;
|
private final PartageRepository partageRepository;
|
||||||
private final PhotoRepository photoRepository;
|
private final PhotoRepository photoRepository;
|
||||||
private final UtilisateurRepository utilisateurRepository;
|
private final UtilisateurRepository utilisateurRepository;
|
||||||
|
private final AlbumRepository albumRepository;
|
||||||
|
|
||||||
public PartageServiceImpl(
|
public PartageServiceImpl(
|
||||||
PartageRepository partageRepository,
|
PartageRepository partageRepository,
|
||||||
PhotoRepository photoRepository,
|
PhotoRepository photoRepository,
|
||||||
UtilisateurRepository utilisateurRepository
|
UtilisateurRepository utilisateurRepository,
|
||||||
|
AlbumRepository albumRepository
|
||||||
) {
|
) {
|
||||||
this.partageRepository = partageRepository;
|
this.partageRepository = partageRepository;
|
||||||
this.photoRepository = photoRepository;
|
this.photoRepository = photoRepository;
|
||||||
this.utilisateurRepository = utilisateurRepository;
|
this.utilisateurRepository = utilisateurRepository;
|
||||||
|
this.albumRepository = albumRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,11 +67,7 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
@Override
|
@Override
|
||||||
public void unshare(Long photoId, String targetEmail) {
|
public void unshare(Long photoId, String targetEmail) {
|
||||||
|
|
||||||
Partage partage = partageRepository.findByPhoto_Id(photoId)
|
Partage partage = partageRepository.findByPhoto_Id(photoId).stream().filter(p -> p.getUtilisateur().getEmail().equals(targetEmail)).findFirst().orElse(null);
|
||||||
.stream()
|
|
||||||
.filter(p -> p.getUtilisateur().getEmail().equals(targetEmail))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if (partage != null)
|
if (partage != null)
|
||||||
partageRepository.delete(partage);
|
partageRepository.delete(partage);
|
||||||
@@ -82,9 +83,7 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
// Photo publique => tout le monde peut voir
|
// Photo publique => tout le monde peut voir
|
||||||
if (photo.getVisibilite() == Photo.Visibilite.PUBLIC)
|
if (photo.getVisibilite() == Photo.Visibilite.PUBLIC)
|
||||||
return true;
|
return true;
|
||||||
Partage partage = partageRepository
|
Partage partage = partageRepository.findByPhoto_IdAndUtilisateur_Email(photoId, email);
|
||||||
.findByPhoto_IdAndUtilisateur_Email(photoId, email)
|
|
||||||
.orElse(null);
|
|
||||||
return partage != null; // READ / COMMENT / ADMIN
|
return partage != null; // READ / COMMENT / ADMIN
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +94,7 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
// propriétaire = admin total
|
// propriétaire = admin total
|
||||||
if (photo.getProprietaire().getEmail().equals(email))
|
if (photo.getProprietaire().getEmail().equals(email))
|
||||||
return true;
|
return true;
|
||||||
Partage partage = partageRepository
|
Partage partage = partageRepository.findByPhoto_IdAndUtilisateur_Email(photoId, email);
|
||||||
.findByPhoto_IdAndUtilisateur_Email(photoId, email)
|
|
||||||
.orElse(null);
|
|
||||||
if (partage == null) return false;
|
if (partage == null) return false;
|
||||||
return partage.getPermission() == Partage.Permission.COMMENT
|
return partage.getPermission() == Partage.Permission.COMMENT
|
||||||
|| partage.getPermission() == Partage.Permission.ADMIN;
|
|| partage.getPermission() == Partage.Permission.ADMIN;
|
||||||
@@ -110,9 +107,7 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
// propriétaire = admin total
|
// propriétaire = admin total
|
||||||
if (photo.getProprietaire().getEmail().equals(email))
|
if (photo.getProprietaire().getEmail().equals(email))
|
||||||
return true;
|
return true;
|
||||||
Partage partage = partageRepository
|
Partage partage = partageRepository.findByPhoto_IdAndUtilisateur_Email(photoId, email);
|
||||||
.findByPhoto_IdAndUtilisateur_Email(photoId, email)
|
|
||||||
.orElse(null);
|
|
||||||
if (partage == null) return false;
|
if (partage == null) return false;
|
||||||
return partage.getPermission() == Partage.Permission.ADMIN;
|
return partage.getPermission() == Partage.Permission.ADMIN;
|
||||||
}
|
}
|
||||||
@@ -121,28 +116,154 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
public void updatePermission(Long photoId, String targetEmail, String newPermission, String requesterEmail) {
|
public void updatePermission(Long photoId, String targetEmail, String newPermission, String requesterEmail) {
|
||||||
Photo photo = photoRepository.findById(photoId)
|
Photo photo = photoRepository.findById(photoId)
|
||||||
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||||
//Vérifier si requester = propriétaire
|
// Si ce n'est pas le propriétaire → vérifier si ADMIN
|
||||||
if (!photo.getProprietaire().getEmail().equals(requesterEmail)) {
|
if (!photo.getProprietaire().getEmail().equals(requesterEmail)) {
|
||||||
// Sinon, vérifier s'il a ADMIN
|
Partage requesterPartage =
|
||||||
Partage requesterPartage = partageRepository
|
partageRepository.findByPhoto_IdAndUtilisateur_Email(photoId, requesterEmail);
|
||||||
.findByPhoto_IdAndUtilisateur_Email(photoId, requesterEmail)
|
if (requesterPartage == null ||
|
||||||
.orElse(null);
|
requesterPartage.getPermission() != Partage.Permission.ADMIN) {
|
||||||
if (requesterPartage == null || requesterPartage.getPermission() != Partage.Permission.ADMIN) {
|
|
||||||
throw new RuntimeException("Vous n’avez pas les droits ADMIN pour modifier les permissions.");
|
throw new RuntimeException("Vous n’avez pas les droits ADMIN pour modifier les permissions.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// OK → modification des droits
|
Partage partage =
|
||||||
Partage partage = partageRepository
|
partageRepository.findByPhoto_IdAndUtilisateur_Email(photoId, targetEmail);
|
||||||
.findByPhoto_IdAndUtilisateur_Email(photoId, targetEmail)
|
if (partage == null)
|
||||||
.orElseThrow(() -> new RuntimeException("Partage introuvable"));
|
throw new RuntimeException("Partage introuvable");
|
||||||
Partage.Permission permission = Partage.Permission.valueOf(newPermission);
|
partage.setPermission(Partage.Permission.valueOf(newPermission));
|
||||||
partage.setPermission(permission);
|
|
||||||
partageRepository.save(partage);
|
partageRepository.save(partage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countShares(Long photoId) {
|
public int countShares(Long photoId) {
|
||||||
return partageRepository.countByPhoto_Id(photoId);
|
return partageRepository.countByPhoto_Id(photoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shareAlbum(Long albumId, String targetEmail, String permissionStr, String ownerEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
if (!album.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
|
throw new RuntimeException("Vous n’êtes pas propriétaire de cet album");
|
||||||
|
Utilisateur target = utilisateurRepository.findByEmail(targetEmail)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Utilisateur introuvable"));
|
||||||
|
if (partageRepository.existsByAlbum_IdAndUtilisateur_Email(albumId, targetEmail))
|
||||||
|
throw new RuntimeException("Cet utilisateur a déjà accès à cet album");
|
||||||
|
//Créer le partage ALBUM
|
||||||
|
Partage.Permission permission = Partage.Permission.valueOf(permissionStr);
|
||||||
|
Partage partage = new Partage();
|
||||||
|
partage.setAlbum(album);
|
||||||
|
partage.setUtilisateur(target);
|
||||||
|
partage.setPermission(permission);
|
||||||
|
partageRepository.save(partage);
|
||||||
|
//Créer le partage PHOTO pour toutes les photos existantes
|
||||||
|
for (Photo photo : album.getPhotos()) {
|
||||||
|
boolean exists = partageRepository.existsByPhoto_IdAndUtilisateur_Email(photo.getId(), targetEmail);
|
||||||
|
if (!exists) {
|
||||||
|
Partage p = new Partage();
|
||||||
|
p.setPhoto(photo);
|
||||||
|
p.setUtilisateur(target);
|
||||||
|
p.setPermission(permission);
|
||||||
|
partageRepository.save(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAlbumPermission(Long albumId, String targetEmail, String newPermission, String ownerEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
if (!album.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
|
throw new RuntimeException("Vous n’êtes pas propriétaire");
|
||||||
|
Partage partageAlbum = partageRepository.findByAlbum_IdAndUtilisateur_Email(albumId, targetEmail);
|
||||||
|
if (partageAlbum == null)
|
||||||
|
throw new RuntimeException("Partage introuvable");
|
||||||
|
Partage.Permission perm = Partage.Permission.valueOf(newPermission);
|
||||||
|
//Mettre à jour permission sur ALBUM
|
||||||
|
partageAlbum.setPermission(perm);
|
||||||
|
partageRepository.save(partageAlbum);
|
||||||
|
//Mettre à jour permissions sur toutes les PHOTOS
|
||||||
|
for (Photo photo : album.getPhotos()) {
|
||||||
|
Partage partagePhoto = partageRepository.findByPhoto_IdAndUtilisateur_Email(photo.getId(), targetEmail);
|
||||||
|
if (partagePhoto != null) {
|
||||||
|
partagePhoto.setPermission(perm);
|
||||||
|
partageRepository.save(partagePhoto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canViewAlbum(Long albumId, String email) {
|
||||||
|
Album album = albumRepository.findById(albumId).orElse(null);
|
||||||
|
if (album == null) return false;
|
||||||
|
if (album.getVisibilite() == Album.Visibilite.PUBLIC)
|
||||||
|
return true;
|
||||||
|
if (album.getProprietaire().getEmail().equals(email))
|
||||||
|
return true;
|
||||||
|
return partageRepository.existsByAlbum_IdAndUtilisateur_Email(albumId, email);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PartageDTO> getAlbumPartages(Long albumId) {
|
||||||
|
return partageRepository.findByAlbum_Id(albumId)
|
||||||
|
.stream()
|
||||||
|
.map(PartageMapper::toDTO)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCommentAlbum(Long albumId, String email) {
|
||||||
|
Album album = albumRepository.findById(albumId).orElse(null);
|
||||||
|
if (album == null) return false;
|
||||||
|
//Le propriétaire : autorisé à tout
|
||||||
|
if (album.getProprietaire().getEmail().equals(email))
|
||||||
|
return true;
|
||||||
|
//Chercher un partage
|
||||||
|
Partage partage = partageRepository.findByAlbum_IdAndUtilisateur_Email(albumId, email);
|
||||||
|
if (partage == null) return false;
|
||||||
|
//COMMENT autorisé pour COMMENT et ADMIN
|
||||||
|
return partage.getPermission() == Partage.Permission.COMMENT
|
||||||
|
|| partage.getPermission() == Partage.Permission.ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canAdminAlbum(Long albumId, String email) {
|
||||||
|
Album album = albumRepository.findById(albumId).orElse(null);
|
||||||
|
if (album == null) return false;
|
||||||
|
//Le propriétaire est toujours ADMIN
|
||||||
|
if (album.getProprietaire().getEmail().equals(email))
|
||||||
|
return true;
|
||||||
|
//hercher un partage
|
||||||
|
Partage partage = partageRepository.findByAlbum_IdAndUtilisateur_Email(albumId, email);
|
||||||
|
if (partage == null) return false;
|
||||||
|
//ADMIN uniquement si permission ADMIN
|
||||||
|
return partage.getPermission() == Partage.Permission.ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAlbumShare(Long albumId, String targetEmail, String ownerEmail) {
|
||||||
|
Album album = albumRepository.findById(albumId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Album introuvable"));
|
||||||
|
// Vérification propriétaire
|
||||||
|
if (!album.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
|
throw new RuntimeException("Vous n’êtes pas propriétaire");
|
||||||
|
//Supprimer le partage ALBUM
|
||||||
|
Partage partageAlbum = partageRepository.findByAlbum_IdAndUtilisateur_Email(albumId, targetEmail);
|
||||||
|
if (partageAlbum != null) {
|
||||||
|
partageRepository.delete(partageAlbum);
|
||||||
|
}
|
||||||
|
//Supprimer les partages sur toutes les photos
|
||||||
|
for (Photo photo : album.getPhotos()) {
|
||||||
|
Partage partagePhoto = partageRepository.findByPhoto_IdAndUtilisateur_Email(photo.getId(), targetEmail);
|
||||||
|
if (partagePhoto != null) {
|
||||||
|
partageRepository.delete(partagePhoto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,11 +134,12 @@ public class PhotoServiceImpl implements PhotoService {
|
|||||||
//============= PHOTOS SHARED WITH USER ==================
|
//============= PHOTOS SHARED WITH USER ==================
|
||||||
@Override
|
@Override
|
||||||
public Page<PhotoDTO> listSharedWith(String email, int page, int size) {
|
public Page<PhotoDTO> listSharedWith(String email, int page, int size) {
|
||||||
List<PhotoDTO> photos =
|
List<PhotoDTO> photos = partageRepository.findByUtilisateur_Email(email)
|
||||||
partageRepository.findByUtilisateur_Email(email)
|
|
||||||
.stream()
|
.stream()
|
||||||
.map(Partage::getPhoto)
|
.map(Partage::getPhoto)
|
||||||
|
.filter(photo -> photo != null)
|
||||||
.map(PhotoMapper::toDTO)
|
.map(PhotoMapper::toDTO)
|
||||||
|
.filter(dto -> dto != null)
|
||||||
.toList();
|
.toList();
|
||||||
int start = page * size;
|
int start = page * size;
|
||||||
int end = Math.min(start + size, photos.size());
|
int end = Math.min(start + size, photos.size());
|
||||||
@@ -147,6 +148,7 @@ public class PhotoServiceImpl implements PhotoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//============= PHOTOS SET AS SHARED BY USER =============
|
//============= PHOTOS SET AS SHARED BY USER =============
|
||||||
@Override
|
@Override
|
||||||
public Page<PhotoDTO> listSharedPhotos(String email, int page, int size) {
|
public Page<PhotoDTO> listSharedPhotos(String email, int page, int size) {
|
||||||
@@ -155,4 +157,15 @@ public class PhotoServiceImpl implements PhotoService {
|
|||||||
.findByProprietaire_EmailAndVisibilite(email, Photo.Visibilite.SHARED, pageable)
|
.findByProprietaire_EmailAndVisibilite(email, Photo.Visibilite.SHARED, pageable)
|
||||||
.map(PhotoMapper::toDTO);
|
.map(PhotoMapper::toDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============= ALL PHOTOS OF USER =======================
|
||||||
|
@Override
|
||||||
|
public List<PhotoDTO> listAllPhotosOfUser(String email) {
|
||||||
|
|
||||||
|
return photoRepository.findByProprietaire_Email(email)
|
||||||
|
.stream()
|
||||||
|
.map(PhotoMapper::toDTO)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
101
src/main/resources/templates/album-detail.html
Normal file
101
src/main/resources/templates/album-detail.html
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Détail album</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a th:href="@{/mes-albums}">⬅ Retour aux albums</a>
|
||||||
|
<h1 th:text="${album.nom}"></h1>
|
||||||
|
<p><b>Description :</b> <span th:text="${album.description}"></span></p>
|
||||||
|
<p><b>Propriétaire :</b> <span th:text="${album.proprietaire.email}"></span></p>
|
||||||
|
<p><b>Visibilité :</b> <span th:text="${album.visibilite}"></span></p>
|
||||||
|
<hr/>
|
||||||
|
<!-- LISTE DES PHOTOS -->
|
||||||
|
<h2>Photos dans l’album</h2>
|
||||||
|
<div th:each="p : ${album.photos}" style="display:inline-block; margin:10px;">
|
||||||
|
<a th:href="@{'/photo/' + ${p.id}}">
|
||||||
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<a th:if="${canAdmin}" th:href="@{'/album/' + ${album.id} + '/remove/' + ${p.id}}"
|
||||||
|
style="color:red;">Retirer</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bloc visible uniquement par le propriétaire ou ADMIN album -->
|
||||||
|
<div th:if="${canAdmin}">
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<!-- AJOUT PHOTO -->
|
||||||
|
<h2>Ajouter une photo</h2>
|
||||||
|
<div th:if="${param.added}" style="color:green; font-weight:bold;">
|
||||||
|
Photo ajoutée !
|
||||||
|
</div>
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/add'}" method="post">
|
||||||
|
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
|
||||||
|
<select name="photoId">
|
||||||
|
<option th:each="p : ${myPhotos}"
|
||||||
|
th:value="${p.id}"
|
||||||
|
th:text="${p.nomFichierOriginal}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Ajouter</button>
|
||||||
|
</form>
|
||||||
|
<hr/>
|
||||||
|
<h3>Gestion des partages de l’album</h3>
|
||||||
|
<div th:if="${param.error}" style="color:red; font-weight:bold;">
|
||||||
|
<span th:text="${param.error}"></span>
|
||||||
|
</div>
|
||||||
|
<!-- FORMULAIRE AJOUT PARTAGE -->
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/share'}" method="post">
|
||||||
|
<label>Email du destinataire :</label>
|
||||||
|
<input type="email" name="email" required>
|
||||||
|
<label>Permission :</label>
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ">Lecture</option>
|
||||||
|
<option value="COMMENT">Commentaire</option>
|
||||||
|
<option value="ADMIN">Admin</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Partager</button>
|
||||||
|
</form>
|
||||||
|
<h4>Utilisateurs ayant accès :</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Utilisateur</th>
|
||||||
|
<th>Permission</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
<tr th:each="p : ${partages}">
|
||||||
|
<td th:text="${p.utilisateur.email}"></td>
|
||||||
|
<!-- FORMULAIRE UPDATE PERMISSION -->
|
||||||
|
<td>
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/share/update'}" method="post">
|
||||||
|
<input type="hidden" name="email" th:value="${p.utilisateur.email}"/>
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ" th:selected="${p.permission == 'READ'}">Lecture</option>
|
||||||
|
<option value="COMMENT" th:selected="${p.permission == 'COMMENT'}">Commentaire</option>
|
||||||
|
<option value="ADMIN" th:selected="${p.permission == 'ADMIN'}">Admin</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Modifier</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a th:href="@{'/album/' + ${album.id} + '/unshare/' + ${p.utilisateur.email}}">Retirer</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<!-- SUPPRESSION ALBUM -->
|
||||||
|
<a th:href="@{'/album/' + ${album.id} + '/delete'}" style="color:red;">
|
||||||
|
Supprimer l’album
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<h1>Bienvenue sur FotoSharing<span th:if="${prenom}" th:text="' : ' + ${prenom}"></span></h1>
|
<h1>Bienvenue sur FotoSharing<span th:if="${prenom}" th:text="' : ' + ${prenom}"></span></h1>
|
||||||
<p><a th:href="@{/upload}">Uploader une photo</a></p>
|
<p><a th:href="@{/upload}">Uploader une photo</a></p>
|
||||||
<p><a th:href="@{/mes-photos}">Voir mes photos</a></p>
|
<p><a th:href="@{/mes-photos}">Voir mes photos</a></p>
|
||||||
|
<p><a th:href="@{/mes-albums}">Voir mes albums</a></p>
|
||||||
<p><a th:href="@{/galerie}">Voir la galerie publique</a></p>
|
<p><a th:href="@{/galerie}">Voir la galerie publique</a></p>
|
||||||
<p>
|
<p>
|
||||||
<form th:action="@{/logout}" method="post" style="display: inline;">
|
<form th:action="@{/logout}" method="post" style="display: inline;">
|
||||||
|
|||||||
70
src/main/resources/templates/mes-albums.html
Normal file
70
src/main/resources/templates/mes-albums.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Mes albums</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Mes albums</h1>
|
||||||
|
|
||||||
|
<!-- FORMULAIRE AJOUT ALBUM -->
|
||||||
|
<h3>Créer un album</h3>
|
||||||
|
<form th:action="@{/albums/create}" method="post">
|
||||||
|
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
|
||||||
|
<label>Nom :</label>
|
||||||
|
<input type="text" name="nom" required><br/>
|
||||||
|
<label>Description :</label>
|
||||||
|
<input type="text" name="description"><br/>
|
||||||
|
<label>Visibilité :</label>
|
||||||
|
<select name="visibilite">
|
||||||
|
<option value="PRIVATE">Privé</option>
|
||||||
|
<option value="SHARED">Partagé</option>
|
||||||
|
<option value="PUBLIC">Public</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Créer</button>
|
||||||
|
</form>
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<!-- LISTE ALBUMS -->
|
||||||
|
<h2>Liste de mes albums</h2>
|
||||||
|
<div th:each="album : ${albums.content}" style="margin:10px 0;">
|
||||||
|
<a th:href="@{'/album/' + ${album.id}}">
|
||||||
|
<b th:text="${album.nom}"></b>
|
||||||
|
</a>
|
||||||
|
<span th:text="'(' + ${album.visibilite} + ')'"></span>
|
||||||
|
<p th:text="${album.description}"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PAGINATION -->
|
||||||
|
<div>
|
||||||
|
<a th:if="${albums.hasPrevious()}"
|
||||||
|
th:href="@{/mes-albums(page=${currentPage - 1})}">⬅</a>
|
||||||
|
<span th:text="${currentPage + 1}"></span>
|
||||||
|
<a th:if="${albums.hasNext()}"
|
||||||
|
th:href="@{/mes-albums(page=${currentPage + 1})}">➡</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<h2>Albums partagés avec moi</h2>
|
||||||
|
<div th:if="${sharedAlbums.isEmpty()}">
|
||||||
|
<p>Aucun album ne vous a été partagé.</p>
|
||||||
|
</div>
|
||||||
|
<div th:unless="${sharedAlbums.isEmpty()}">
|
||||||
|
<div class="album-list">
|
||||||
|
<div th:each="album : ${sharedAlbums}" class="album-item">
|
||||||
|
<a th:href="@{'/album/' + ${album.id}}">
|
||||||
|
<strong th:text="${album.nom}"></strong>
|
||||||
|
</a>
|
||||||
|
<p>
|
||||||
|
Partagé par :
|
||||||
|
<span th:text="${album.proprietaire.email}"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<p><a th:href="@{/}">Retour accueil</a></p>
|
<p><a th:href="@{/}">Retour accueil</a></p>
|
||||||
<h2>Mes photos privées</h2>
|
<h2>Mes photos privées</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPrivees.content}"
|
<a th:each="p : ${photosPrivees.content}" th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<h2>Mes photos publiques</h2>
|
<h2>Mes photos publiques</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPubliques.content}"
|
<a th:each="p : ${photosPubliques.content}" th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
<h2>Mes photos partagées</h2>
|
<h2>Mes photos partagées</h2>
|
||||||
<div style="display:flex; gap:20px; flex-wrap:wrap;">
|
<div style="display:flex; gap:20px; flex-wrap:wrap;">
|
||||||
<div th:each="p : ${mesPhotosPartagees.content}">
|
<div th:each="p : ${mesPhotosPartagees.content}" th:if="${p != null}">
|
||||||
<a th:href="@{'/photo/' + ${p.id}}">
|
<a th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"
|
||||||
style="display:block; border:1px solid #ccc;"/>
|
style="display:block; border:1px solid #ccc;"/>
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
<h2>Photos partagées avec moi</h2>
|
<h2>Photos partagées avec moi</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPartagees.content}"
|
<a th:each="p : ${photosPartagees.content}"
|
||||||
|
th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Binary file not shown.
BIN
target/classes/local/epul4a/fotosharing/dto/AlbumDTO.class
Normal file
BIN
target/classes/local/epul4a/fotosharing/dto/AlbumDTO.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/local/epul4a/fotosharing/mapper/AlbumMapper.class
Normal file
BIN
target/classes/local/epul4a/fotosharing/mapper/AlbumMapper.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/classes/local/epul4a/fotosharing/model/Album.class
Normal file
BIN
target/classes/local/epul4a/fotosharing/model/Album.class
Normal file
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.
101
target/classes/templates/album-detail.html
Normal file
101
target/classes/templates/album-detail.html
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Détail album</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a th:href="@{/mes-albums}">⬅ Retour aux albums</a>
|
||||||
|
<h1 th:text="${album.nom}"></h1>
|
||||||
|
<p><b>Description :</b> <span th:text="${album.description}"></span></p>
|
||||||
|
<p><b>Propriétaire :</b> <span th:text="${album.proprietaire.email}"></span></p>
|
||||||
|
<p><b>Visibilité :</b> <span th:text="${album.visibilite}"></span></p>
|
||||||
|
<hr/>
|
||||||
|
<!-- LISTE DES PHOTOS -->
|
||||||
|
<h2>Photos dans l’album</h2>
|
||||||
|
<div th:each="p : ${album.photos}" style="display:inline-block; margin:10px;">
|
||||||
|
<a th:href="@{'/photo/' + ${p.id}}">
|
||||||
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<a th:if="${canAdmin}" th:href="@{'/album/' + ${album.id} + '/remove/' + ${p.id}}"
|
||||||
|
style="color:red;">Retirer</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bloc visible uniquement par le propriétaire ou ADMIN album -->
|
||||||
|
<div th:if="${canAdmin}">
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<!-- AJOUT PHOTO -->
|
||||||
|
<h2>Ajouter une photo</h2>
|
||||||
|
<div th:if="${param.added}" style="color:green; font-weight:bold;">
|
||||||
|
Photo ajoutée !
|
||||||
|
</div>
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/add'}" method="post">
|
||||||
|
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
|
||||||
|
<select name="photoId">
|
||||||
|
<option th:each="p : ${myPhotos}"
|
||||||
|
th:value="${p.id}"
|
||||||
|
th:text="${p.nomFichierOriginal}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Ajouter</button>
|
||||||
|
</form>
|
||||||
|
<hr/>
|
||||||
|
<h3>Gestion des partages de l’album</h3>
|
||||||
|
<div th:if="${param.error}" style="color:red; font-weight:bold;">
|
||||||
|
<span th:text="${param.error}"></span>
|
||||||
|
</div>
|
||||||
|
<!-- FORMULAIRE AJOUT PARTAGE -->
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/share'}" method="post">
|
||||||
|
<label>Email du destinataire :</label>
|
||||||
|
<input type="email" name="email" required>
|
||||||
|
<label>Permission :</label>
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ">Lecture</option>
|
||||||
|
<option value="COMMENT">Commentaire</option>
|
||||||
|
<option value="ADMIN">Admin</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Partager</button>
|
||||||
|
</form>
|
||||||
|
<h4>Utilisateurs ayant accès :</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Utilisateur</th>
|
||||||
|
<th>Permission</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
<tr th:each="p : ${partages}">
|
||||||
|
<td th:text="${p.utilisateur.email}"></td>
|
||||||
|
<!-- FORMULAIRE UPDATE PERMISSION -->
|
||||||
|
<td>
|
||||||
|
<form th:action="@{'/album/' + ${album.id} + '/share/update'}" method="post">
|
||||||
|
<input type="hidden" name="email" th:value="${p.utilisateur.email}"/>
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ" th:selected="${p.permission == 'READ'}">Lecture</option>
|
||||||
|
<option value="COMMENT" th:selected="${p.permission == 'COMMENT'}">Commentaire</option>
|
||||||
|
<option value="ADMIN" th:selected="${p.permission == 'ADMIN'}">Admin</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Modifier</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a th:href="@{'/album/' + ${album.id} + '/unshare/' + ${p.utilisateur.email}}">Retirer</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<!-- SUPPRESSION ALBUM -->
|
||||||
|
<a th:href="@{'/album/' + ${album.id} + '/delete'}" style="color:red;">
|
||||||
|
Supprimer l’album
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<h1>Bienvenue sur FotoSharing<span th:if="${prenom}" th:text="' : ' + ${prenom}"></span></h1>
|
<h1>Bienvenue sur FotoSharing<span th:if="${prenom}" th:text="' : ' + ${prenom}"></span></h1>
|
||||||
<p><a th:href="@{/upload}">Uploader une photo</a></p>
|
<p><a th:href="@{/upload}">Uploader une photo</a></p>
|
||||||
<p><a th:href="@{/mes-photos}">Voir mes photos</a></p>
|
<p><a th:href="@{/mes-photos}">Voir mes photos</a></p>
|
||||||
|
<p><a th:href="@{/mes-albums}">Voir mes albums</a></p>
|
||||||
<p><a th:href="@{/galerie}">Voir la galerie publique</a></p>
|
<p><a th:href="@{/galerie}">Voir la galerie publique</a></p>
|
||||||
<p>
|
<p>
|
||||||
<form th:action="@{/logout}" method="post" style="display: inline;">
|
<form th:action="@{/logout}" method="post" style="display: inline;">
|
||||||
|
|||||||
70
target/classes/templates/mes-albums.html
Normal file
70
target/classes/templates/mes-albums.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Mes albums</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Mes albums</h1>
|
||||||
|
|
||||||
|
<!-- FORMULAIRE AJOUT ALBUM -->
|
||||||
|
<h3>Créer un album</h3>
|
||||||
|
<form th:action="@{/albums/create}" method="post">
|
||||||
|
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
|
||||||
|
<label>Nom :</label>
|
||||||
|
<input type="text" name="nom" required><br/>
|
||||||
|
<label>Description :</label>
|
||||||
|
<input type="text" name="description"><br/>
|
||||||
|
<label>Visibilité :</label>
|
||||||
|
<select name="visibilite">
|
||||||
|
<option value="PRIVATE">Privé</option>
|
||||||
|
<option value="SHARED">Partagé</option>
|
||||||
|
<option value="PUBLIC">Public</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Créer</button>
|
||||||
|
</form>
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<!-- LISTE ALBUMS -->
|
||||||
|
<h2>Liste de mes albums</h2>
|
||||||
|
<div th:each="album : ${albums.content}" style="margin:10px 0;">
|
||||||
|
<a th:href="@{'/album/' + ${album.id}}">
|
||||||
|
<b th:text="${album.nom}"></b>
|
||||||
|
</a>
|
||||||
|
<span th:text="'(' + ${album.visibilite} + ')'"></span>
|
||||||
|
<p th:text="${album.description}"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PAGINATION -->
|
||||||
|
<div>
|
||||||
|
<a th:if="${albums.hasPrevious()}"
|
||||||
|
th:href="@{/mes-albums(page=${currentPage - 1})}">⬅</a>
|
||||||
|
<span th:text="${currentPage + 1}"></span>
|
||||||
|
<a th:if="${albums.hasNext()}"
|
||||||
|
th:href="@{/mes-albums(page=${currentPage + 1})}">➡</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<h2>Albums partagés avec moi</h2>
|
||||||
|
<div th:if="${sharedAlbums.isEmpty()}">
|
||||||
|
<p>Aucun album ne vous a été partagé.</p>
|
||||||
|
</div>
|
||||||
|
<div th:unless="${sharedAlbums.isEmpty()}">
|
||||||
|
<div class="album-list">
|
||||||
|
<div th:each="album : ${sharedAlbums}" class="album-item">
|
||||||
|
<a th:href="@{'/album/' + ${album.id}}">
|
||||||
|
<strong th:text="${album.nom}"></strong>
|
||||||
|
</a>
|
||||||
|
<p>
|
||||||
|
Partagé par :
|
||||||
|
<span th:text="${album.proprietaire.email}"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<p><a th:href="@{/}">Retour accueil</a></p>
|
<p><a th:href="@{/}">Retour accueil</a></p>
|
||||||
<h2>Mes photos privées</h2>
|
<h2>Mes photos privées</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPrivees.content}"
|
<a th:each="p : ${photosPrivees.content}" th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<h2>Mes photos publiques</h2>
|
<h2>Mes photos publiques</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPubliques.content}"
|
<a th:each="p : ${photosPubliques.content}" th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
<h2>Mes photos partagées</h2>
|
<h2>Mes photos partagées</h2>
|
||||||
<div style="display:flex; gap:20px; flex-wrap:wrap;">
|
<div style="display:flex; gap:20px; flex-wrap:wrap;">
|
||||||
<div th:each="p : ${mesPhotosPartagees.content}">
|
<div th:each="p : ${mesPhotosPartagees.content}" th:if="${p != null}">
|
||||||
<a th:href="@{'/photo/' + ${p.id}}">
|
<a th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"
|
||||||
style="display:block; border:1px solid #ccc;"/>
|
style="display:block; border:1px solid #ccc;"/>
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
<h2>Photos partagées avec moi</h2>
|
<h2>Photos partagées avec moi</h2>
|
||||||
<div>
|
<div>
|
||||||
<a th:each="p : ${photosPartagees.content}"
|
<a th:each="p : ${photosPartagees.content}"
|
||||||
|
th:if="${p != null}"
|
||||||
th:href="@{'/photo/' + ${p.id}}">
|
th:href="@{'/photo/' + ${p.id}}">
|
||||||
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
<img th:src="@{'/photo/' + ${p.id} + '/raw'}" width="120"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user