feat: backend returns whether user liked each post (efficiently using sets).

This commit is contained in:
sBubshait 2025-07-23 14:23:12 +03:00
parent 221136b4ee
commit 037bdf64b8
3 changed files with 67 additions and 5 deletions

View File

@ -11,6 +11,7 @@ public class PostResponseDTO {
private String body;
private String likes;
private String comments;
private boolean liked;
private LocalDateTime creationDate;
public PostResponseDTO() {}
@ -21,6 +22,17 @@ public class PostResponseDTO {
this.body = post.getBody();
this.likes = String.valueOf(post.getLikes());
this.comments = String.valueOf(post.getComments());
this.liked = false; // Default value, will be set by service
this.creationDate = post.getCreationDate();
}
public PostResponseDTO(Post post, User creator, boolean liked) {
this.id = String.valueOf(post.getId());
this.creator = new CreatorDTO(creator);
this.body = post.getBody();
this.likes = String.valueOf(post.getLikes());
this.comments = String.valueOf(post.getComments());
this.liked = liked;
this.creationDate = post.getCreationDate();
}
@ -64,6 +76,14 @@ public class PostResponseDTO {
this.comments = comments;
}
public boolean isLiked() {
return liked;
}
public void setLiked(boolean liked) {
this.liked = liked;
}
public LocalDateTime getCreationDate() {
return creationDate;
}

View File

@ -2,9 +2,13 @@ package online.wesal.wesal.repository;
import online.wesal.wesal.entity.PostLike;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Repository
public interface PostLikeRepository extends JpaRepository<PostLike, Long> {
@ -12,4 +16,10 @@ public interface PostLikeRepository extends JpaRepository<PostLike, Long> {
boolean existsByPostIdAndUserId(Long postId, Long userId);
void deleteByPostIdAndUserId(Long postId, Long userId);
long countByPostId(Long postId);
@Query("SELECT pl.postId FROM PostLike pl WHERE pl.userId = :userId AND pl.postId IN :postIds")
Set<Long> findLikedPostIdsByUserIdAndPostIds(@Param("userId") Long userId, @Param("postIds") List<Long> postIds);
@Query("SELECT pl.postId FROM PostLike pl WHERE pl.userId = :userId")
Set<Long> findAllLikedPostIdsByUserId(@Param("userId") Long userId);
}

View File

@ -14,6 +14,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@ -41,16 +42,30 @@ public class PostService {
LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
List<Post> posts = postRepository.findAllPostsWithinLast7Days(sevenDaysAgo);
User currentUser = userService.getCurrentUser();
Long currentUserId = currentUser.getId();
// Get all unique creator IDs
List<Long> creatorIds = posts.stream()
.map(Post::getCreatorId)
.distinct()
.collect(Collectors.toList());
// Get all post IDs
List<Long> postIds = posts.stream()
.map(Post::getId)
.collect(Collectors.toList());
// Fetch creators in one query
Map<Long, User> creators = userRepository.findAllById(creatorIds).stream()
.collect(Collectors.toMap(User::getId, user -> user));
// Fetch user's likes for these posts in one query
Set<Long> likedPostIds = postLikeRepository.findLikedPostIdsByUserIdAndPostIds(currentUserId, postIds);
return posts.stream()
.map(post -> new PostResponseDTO(post, creators.get(post.getCreatorId())))
.map(post -> new PostResponseDTO(post, creators.get(post.getCreatorId()),
likedPostIds.contains(post.getId())))
.collect(Collectors.toList());
}
@ -59,8 +74,19 @@ public class PostService {
User creator = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
User currentUser = userService.getCurrentUser();
Long currentUserId = currentUser.getId();
// Get all post IDs
List<Long> postIds = posts.stream()
.map(Post::getId)
.collect(Collectors.toList());
// Fetch user's likes for these posts in one query
Set<Long> likedPostIds = postLikeRepository.findLikedPostIdsByUserIdAndPostIds(currentUserId, postIds);
return posts.stream()
.map(post -> new PostResponseDTO(post, creator))
.map(post -> new PostResponseDTO(post, creator, likedPostIds.contains(post.getId())))
.collect(Collectors.toList());
}
@ -68,7 +94,7 @@ public class PostService {
User currentUser = userService.getCurrentUser();
Post post = new Post(currentUser.getId(), body);
post = postRepository.save(post);
return new PostResponseDTO(post, currentUser);
return new PostResponseDTO(post, currentUser, false); // New post is not liked by default
}
@Transactional
@ -95,7 +121,10 @@ public class PostService {
User creator = userRepository.findById(post.getCreatorId())
.orElseThrow(() -> new RuntimeException("Creator not found"));
return new PostResponseDTO(post, creator);
// Check if user now likes this post
boolean isLiked = postLikeRepository.existsByPostIdAndUserId(postId, userId);
return new PostResponseDTO(post, creator, isLiked);
}
@Transactional
@ -121,6 +150,9 @@ public class PostService {
User creator = userRepository.findById(post.getCreatorId())
.orElseThrow(() -> new RuntimeException("Creator not found"));
return new PostResponseDTO(post, creator);
// Check if user now likes this post
boolean isLiked = postLikeRepository.existsByPostIdAndUserId(postId, userId);
return new PostResponseDTO(post, creator, isLiked);
}
}