- 이번 시간에는 아래와 같이 본인이 구독한 사용자가 업로드한 글을 바로 볼 수 있는 스토리 페이지를 구현해보려고 합니다.
- 해당 페이지를 구성하고 있는 요소들을 잠깐 살펴보면 우선 제일 위에 사용자 정보가 드러나고, 업로드한 사진, 사진 설명, 좋아요 수, 댓글 정보가 나타나고 있습니다.
- 아직 좋아요와 댓글 기능을 구현하지 않았으니 이를 제외한 나머지만으로 먼저 구현해보도록 하겠습니다.
📝 Repository
- 우선 해당 페이지에는 현재 접속중인 사용자가 구독중인 사용자의 글이 보여져야 하기 때문에 우리는 아래와 같은 쿼리를 작성할 수 있습니다.
package com.cos.photogram.domain.image;
...
public interface ImageRepository extends JpaRepository<Image, Long>{
@Query(value = "SELECT * FROM image WHERE user_id IN (SELECT to_user_id FROM subscribe WHERE from_user_id = :principal_id) ORDER BY id DESC", nativeQuery = true)
Page<Image> story(Long principal_id, Pageable pageable);
}
- Pageable은 이후 사용자의 글을 페이징을 통해 정해진 수만큼만 출력하도록 하기 위해 사용하였습니다.
참고: 정렬의 경우 @PageableDefault 어노테이션을 통해 손쉽게 설정할 수 있으나, 우리는 네이티브 쿼리를 직접 생성하였기 때문에 해당 설정이 동작하지 않아 위처럼 직접 정렬 쿼리를 작성해주었습니다.
📝 Service
package com.cos.photogram.service;
...
@RequiredArgsConstructor
@Service
public class ImageService {
private final ImageRepository imageRepository;
...
@Transactional(readOnly = true)
public Page<Image> story(Long principalId, Pageable pageable) {
return imageRepository.story(principalId, pageable);
}
}
📝 Controller
package com.cos.photogram.web.api;
...
@RequiredArgsConstructor
@RestController
public class ImageApiController {
private final ImageService imageService;
@GetMapping("/api/image")
public ResponseEntity<?> story(@AuthenticationPrincipal PrincipalDetails principalDetails,
@PageableDefault(size = 3) Pageable pageable) {
Page<Image> images = imageService.story(principalDetails.getUser().getId(), pageable);
return new ResponseEntity<>(new CMRespDto<>(1, "이미지 스토리 불러오기 성공", images), HttpStatus.OK);
}
}
📝 Javascript
let page = 0;
// (1) 스토리 로드하기
function storyLoad() {
$.ajax({
url: `/api/image?page=${page}`,
dataType: "json"
}).done(resp => {
console.log(resp);
resp.data.content.forEach((image) => {
let item = getStoryItem(image);
$("#storyList").append(item);
});
}).fail(error => {
console.log(error);
});
}
storyLoad();
function getStoryItem(image) {
let item = `<div class="story-list__item">
<div class="sl__item__header">
<div>
<img class="profile-image" src="/upload/${image.user.profile_image_url}"
onerror="this.src='/images/person.jpeg'" />
</div>
<div>${image.user.username}</div>
</div>
<div class="sl__item__img">
<img src="/upload/${image.post_image_url}" />
</div>
<div class="sl__item__contents">
<div class="sl__item__contents__icon">
<button>
<i class="fas fa-heart active" id="storyLikeIcon-1" onclick="toggleLike()"></i>
</button>
</div>
<span class="like"><b id="storyLikeCount-1">3 </b>likes</span>
<div class="sl__item__contents__content">
<p>${image.caption}</p>
</div>
<div id="storyCommentList-1">
<div class="sl__item__contents__comment" id="storyCommentItem-1"">
<p>
<b>Lovely :</b> 부럽습니다.
</p>
<button>
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div class="sl__item__input">
<input type="text" placeholder="댓글 달기..." id="storyCommentInput-1" />
<button type="button" onClick="addComment()">게시</button>
</div>
</div>
</div>`
return item;
}
// (2) 스토리 스크롤 페이징하기
$(window).scroll(() => {
let checkScroll = $(window).scrollTop() - ($(document).height() - $(window).height());
if(checkScroll > 0){
page++;
storyLoad();
}
});
📝 Result
- 이후 결과를 확인해보면 사용자가 구독한 사용자의 업로드 정보가 알맞게 출력되는 것을 확인할 수 있으며 스크롤을 아래로 내려 끝에 다다르는 순간 페이징되어 새롭게 글이 출력되는 것을 확인할 수 있습니다.
'🚗 Backend Toy Project > Photogram' 카테고리의 다른 글
[Photogram] 인기 페이지 구현 (2) | 2022.07.16 |
---|---|
[Photogram] 좋아요 구현하기 (0) | 2022.07.15 |
[Photogram] 구독하기 - 구독 모달 (0) | 2022.07.14 |
[Photogram] 구독하기 - 기능 구현 (0) | 2022.07.12 |
[Photogram] 구독하기 - 뷰 렌더링 (0) | 2022.07.12 |