Skip to content

Commit

Permalink
[FE] Feat #133: 댓글 리스트 컴포넌트 보일 때 댓글 입력 컴포넌트 랜더링 되도록 기능 추가
Browse files Browse the repository at this point in the history
Change-Id: I25ef17876ba0016799d4d4e3c74da84f1f3d4dd0
  • Loading branch information
leewooseong committed Feb 7, 2024
1 parent e26d01c commit d82b4f4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 10 deletions.
25 changes: 21 additions & 4 deletions frontend/src/pages/Bucket/BucketDetail/Comment/CommentInput.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import { ChangeEvent, useState } from 'react'
import { ChangeEvent, useRef } from 'react'
import { useCommentStore } from '../../../../store/detailStore'

interface ICommentInput {
setIsInputFocused: React.Dispatch<React.SetStateAction<boolean>>
}

// Todo: Pwa 환경에서 해당 컴포넌트가 언마운트 될때 키보드가 내려가는지 확인 필요
const CommentInput = ({ setIsInputFocused }: ICommentInput) => {
const { commentText, setCommentText } = useCommentStore()
const inputRef = useRef<HTMLInputElement>(null)

const CommentInput = () => {
const [commentText, setCommentText] = useState('')
const handleCommentChange = (event: ChangeEvent<HTMLInputElement>) => {
const text = event.currentTarget.value
setCommentText(text)
}
const handleFocusInput = () => {
setIsInputFocused(true)
}
const handleBlurInput = () => {
setIsInputFocused(false)
}

return (
<div className="fixed bottom-0 flex w-full px-6 py-3 bg-white border-t-[1px] border-gray">
<div className="comment-input fixed bottom-0 flex w-full px-6 py-3 bg-white border-t-[1px] border-gray">
<img src="/public/defaultProfile.svg" />
<input
ref={inputRef}
type="text"
placeholder="댓글 입력하기..."
value={commentText}
onChange={handleCommentChange}
onFocus={handleFocusInput}
onBlur={handleBlurInput}
className="px-3 grow focus:outline-none"
/>
<button type="button" className={`${commentText ? 'text-point1' : 'text-gray'}`}>
Expand Down
46 changes: 42 additions & 4 deletions frontend/src/pages/Bucket/BucketDetail/Comment/CommentList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Comment from './Comment'
import { ICommentItem } from '../../../../interfaces'
import { useEffect, useRef } from 'react'
import { useCommentStore } from '../../../../store/detailStore'

const commentInfo = {
totalPages: 0,
Expand Down Expand Up @@ -87,13 +89,49 @@ const commentInfo = {
last: true,
empty: true,
}
interface ICommentListProps {
isInputFocused: boolean
setIsInputShown: React.Dispatch<React.SetStateAction<boolean>>
}

// Todo : Api 데이터 타입 지정 후 as 삭제 예정
const CommentList = () => {
const CommentList = ({ isInputFocused, setIsInputShown }: ICommentListProps) => {
const { commentText } = useCommentStore()
const targetRef = useRef<HTMLUListElement>(null)

// 전역 이벤트 핸들러에서 closure 때문에 최신 state 값을 못 가져오는 문제 해결을 위한 useEffect
useEffect(() => {
window.addEventListener('scroll', checkTargetIsShown)
checkTargetIsShown() // 초기 로드 시에도 위치 확인

return () => {
window.removeEventListener('scroll', checkTargetIsShown)
}
}, [commentText, isInputFocused])

const checkTargetIsShown = () => {
if (targetRef.current) {
const targetLocationInfo = targetRef.current.getBoundingClientRect()
const isVisible = targetLocationInfo.top < window.innerHeight

// 타겟이 보일 때 -> 항상 input이 보이도록 설정
if (isVisible === true) {
setIsInputShown(true)
return
}
if (isVisible === false && commentText.length === 0 && !isInputFocused) {
setIsInputShown(false)
return
}
}
}

return (
<ul>
{commentInfo.content.map((comment) => (
<Comment commentInfo={comment as ICommentItem} />
<ul ref={targetRef}>
{commentInfo.content.map((comment, index) => (
<li key={index}>
<Comment commentInfo={comment as ICommentItem} />
</li>
))}
</ul>
)
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/pages/Bucket/BucketDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useParams } from 'react-router-dom'
import Reaction from './Reaction'
import CommentList from './Comment/CommentList'
import CommentInput from './Comment/CommentInput'
import { useState } from 'react'

const userInfo: UserInfoType = {
userId: 1,
Expand Down Expand Up @@ -49,6 +50,8 @@ const bucketInfo: IBucketInfo = {
}

const BucketDetail = () => {
const [isInputShown, setIsInputShown] = useState(false)
const [isInputFocused, setIsInputFocused] = useState(false)
const { goBack } = useRouter()
const { bucketId } = useParams()

Expand Down Expand Up @@ -97,9 +100,9 @@ const BucketDetail = () => {
: bucketId && <WriteReviewButton id={bucketId} />}
</div>
<Reaction />
<CommentList />
<CommentList isInputFocused={isInputFocused} setIsInputShown={setIsInputShown} />
</WithHeaderLayout>
<CommentInput />
{isInputShown && <CommentInput setIsInputFocused={setIsInputFocused} />}
</>
)
}
Expand Down

0 comments on commit d82b4f4

Please sign in to comment.