Skip to content

fix : 마음일기 UI 수정#28

Merged
jpark0506 merged 2 commits intodevfrom
fix/diary-list-ui-fix
Feb 22, 2026
Merged

fix : 마음일기 UI 수정#28
jpark0506 merged 2 commits intodevfrom
fix/diary-list-ui-fix

Conversation

@jpark0506
Copy link
Collaborator

@jpark0506 jpark0506 commented Feb 22, 2026

어떤 기능인가요?

  • 마음일기 UI 수정
    • 글씨 크기 수정
    • 녹음 요소 가운데 정렬

작업 상세 내용

참고할만한 자료(선택)

Summary by CodeRabbit

  • Style
    • 배너 텍스트 크기를 확대했습니다.
    • 녹음 인터페이스 레이아웃을 재정렬하여 수직 구조로 개선했습니다.
    • 녹음 제어 버튼들을 중앙 집중식으로 배치하고 저장 상태 시각화를 개선했습니다.
    • 타이머 폰트 크기를 조정했습니다.

@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

일기 UI 컴포넌트의 녹음 인터페이스 레이아웃을 재구성하여 녹음 타이머와 파형 시각화를 새로운 중앙 정렬 구조로 이동하고, 제어 버튼들의 위치와 조건부 렌더링을 조정했습니다. 녹음 타이머의 글꼴 크기도 함께 수정되었습니다.

Changes

Cohort / File(s) Summary
Diary Recording Interface Layout
app/(tabs-user)/diary.tsx
녹음 UI를 수직 흐름으로 재구성하여 RecordingTimer와 WaveformVisualizer를 새로운 중앙 정렬 구조로 이동. 고정 크기의 원형 마이크 버튼을 중심에 배치하고, 완료/취소 버튼의 조건부 렌더링 및 위치 조정. 저장 상태 시 처리중 표시로 변경. 상단 배너 텍스트 크기를 text-xl에서 text-2xl로 증가.
Recording Timer Styling
shared/ui/audio/recording-timer.tsx
Text 요소의 글꼴 크기를 text-lg에서 text-[21px]로 변경하여 정확한 픽셀 크기 적용.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • feat : 통계 및 내 정보 연결 #6: 동일한 diary.tsx 및 recording-timer.tsx 파일을 수정하여 녹음 UI 레이아웃과 타이머 프레젠테이션 변경 사항이 겹치는 관련 PR입니다.

Poem

🐰 녹음 버튼이 춤을 춘다

원형 무대 위에 마이크가 돋보이고,
타이머는 새로운 옷을 입고 반짝이네요.
버튼들 정렬하여 흐름을 맞추고,
UI 정원이 더욱 아름다워졌어요! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 변경 사항의 주요 내용을 정확하게 반영하며, 마음일기 UI 수정이라는 핵심 변화를 명확하게 요약하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/diary-list-ui-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jpark0506
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/(tabs-user)/diary.tsx (1)

327-402: 취소/완료 버튼의 absolute 배치 — 작은 화면에서 겹침 가능성이 있습니다.

left-8/right-8으로 absolute 배치된 취소·완료 버튼이 중앙의 큰 녹음 버튼(88×2=176px 영역)과 좁은 화면에서 겹칠 수 있습니다. 현재 기기 대응이 충분한지 확인해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(tabs-user)/diary.tsx around lines 327 - 402, The side "취소"/"완료" buttons
are absolutely positioned with left-8/right-8 and can overlap the central record
area (BUTTON_SIZE * MAX_RING_SCALE) on narrow screens; update the layout to
compute available width (e.g., via Dimensions.get('window').width or use
onLayout) and conditionally adjust positioning: either switch from absolute
left-8/right-8 to a responsive flex row with space-between around the central
control (so the central View with BUTTON_SIZE and MAX_RING_SCALE stays centered)
or hide/relocate the side buttons when window width < (BUTTON_SIZE *
MAX_RING_SCALE + required side padding). Modify the code paths around the Views
that render the side buttons (the Views wrapping Button and the central View
using BUTTON_SIZE/MAX_RING_SCALE and recordingState.isRecording) and the
handlers handleReset/handleSaveServer so behavior remains unchanged when buttons
are repositioned or hidden.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/`(tabs-user)/diary.tsx:
- Around line 306-312: The RecordingTimer is always shown because isPaused is
set to !recordingState.isRecording; change the logic so the timer only appears
when there's an actual recorded duration by using recordingState.durationMillis
> 0. Update the RecordingTimer props/conditional render around RecordingTimer
(referencing RecordingTimer, recordingState.durationMillis,
recordingState.isRecording) so isPaused becomes (!recordingState.isRecording &&
recordingState.durationMillis > 0) and/or wrap the <RecordingTimer ... /> render
in a guard that only renders when recordingState.durationMillis > 0.
- Around line 361-365: The Icon component is being passed width and height props
which are ignored because Icon only accepts { name, size, onPress }; update the
usages where Icon is rendered (the Icon with name computed via
recordingState.isRecording and the smaller Icon at the later usage) to pass a
single numeric size prop (e.g., size={40} and size={20}) instead of
width/height, or alternatively update the Icon component signature to accept and
map width/height into size; locate the Icon calls by the name prop usage
(name={recordingState.isRecording ? "Stop" : "Mic"}) and change to size={40}
(and the other Icon to size={20}) so the icons render at the intended
dimensions.

---

Nitpick comments:
In `@app/`(tabs-user)/diary.tsx:
- Around line 327-402: The side "취소"/"완료" buttons are absolutely positioned with
left-8/right-8 and can overlap the central record area (BUTTON_SIZE *
MAX_RING_SCALE) on narrow screens; update the layout to compute available width
(e.g., via Dimensions.get('window').width or use onLayout) and conditionally
adjust positioning: either switch from absolute left-8/right-8 to a responsive
flex row with space-between around the central control (so the central View with
BUTTON_SIZE and MAX_RING_SCALE stays centered) or hide/relocate the side buttons
when window width < (BUTTON_SIZE * MAX_RING_SCALE + required side padding).
Modify the code paths around the Views that render the side buttons (the Views
wrapping Button and the central View using BUTTON_SIZE/MAX_RING_SCALE and
recordingState.isRecording) and the handlers handleReset/handleSaveServer so
behavior remains unchanged when buttons are repositioned or hidden.

Comment on lines +306 to +312
<View className="flex items-center justify-center mb-3">
<RecordingTimer
duration={recordingState.durationMillis / 1000}
isRecording={recordingState.isRecording}
isPaused={!recordingState.isRecording}
/>
)}
{/* 실제 버튼 - 크기 고정 */}
<TouchableOpacity
className="rounded-full flex items-center justify-center bg-main500"
style={{ width: BUTTON_SIZE, height: BUTTON_SIZE }}
onPress={handleMainButtonPress}
>
<Icon
name={recordingState.isRecording ? "Stop" : "Mic"}
width={40}
height={40}
</View>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

isPaused 로직 오류 — 녹음 시작 전에도 타이머가 항상 표시됩니다.

isPaused={!recordingState.isRecording}으로 설정하면 isRecordingisPaused 중 하나가 항상 true이므로, RecordingTimernull을 반환하지 않습니다. 결과적으로 녹음을 시작하지 않은 초기 상태에서도 "00:00" 타이머가 표시됩니다.

durationMillis > 0 조건을 추가하여 실제로 녹음이 일시정지된 경우에만 타이머를 표시해야 합니다.

🐛 수정 제안
              <RecordingTimer
                duration={recordingState.durationMillis / 1000}
                isRecording={recordingState.isRecording}
-               isPaused={!recordingState.isRecording}
+               isPaused={!recordingState.isRecording && recordingState.durationMillis > 0}
              />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<View className="flex items-center justify-center mb-3">
<RecordingTimer
duration={recordingState.durationMillis / 1000}
isRecording={recordingState.isRecording}
isPaused={!recordingState.isRecording}
/>
)}
{/* 실제 버튼 - 크기 고정 */}
<TouchableOpacity
className="rounded-full flex items-center justify-center bg-main500"
style={{ width: BUTTON_SIZE, height: BUTTON_SIZE }}
onPress={handleMainButtonPress}
>
<Icon
name={recordingState.isRecording ? "Stop" : "Mic"}
width={40}
height={40}
</View>
<View className="flex items-center justify-center mb-3">
<RecordingTimer
duration={recordingState.durationMillis / 1000}
isRecording={recordingState.isRecording}
isPaused={!recordingState.isRecording && recordingState.durationMillis > 0}
/>
</View>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(tabs-user)/diary.tsx around lines 306 - 312, The RecordingTimer is
always shown because isPaused is set to !recordingState.isRecording; change the
logic so the timer only appears when there's an actual recorded duration by
using recordingState.durationMillis > 0. Update the RecordingTimer
props/conditional render around RecordingTimer (referencing RecordingTimer,
recordingState.durationMillis, recordingState.isRecording) so isPaused becomes
(!recordingState.isRecording && recordingState.durationMillis > 0) and/or wrap
the <RecordingTimer ... /> render in a guard that only renders when
recordingState.durationMillis > 0.

Comment on lines 361 to 365
<Icon
name={recordingState.isRecording ? "Stop" : "Mic"}
width={40}
height={40}
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the Icon/SvgIcon component definition
echo "=== Finding Icon/SvgIcon component ==="
find . -type f -name "*.tsx" -o -name "*.ts" | xargs grep -l "export.*Icon" | grep -E "(SvgIcon|Icon)" | head -20

echo ""
echo "=== Searching for SvgIcon.tsx ==="
find . -type f -name "SvgIcon.tsx"

echo ""
echo "=== Searching for Icon component definition ==="
find . -type f \( -name "*.tsx" -o -name "*.ts" \) | xargs grep -l "interface IconProps\|type IconProps" 2>/dev/null

Repository: safori-team/CARING-front

Length of output: 330


🏁 Script executed:

#!/bin/bash
# Check the specific file and lines mentioned
echo "=== Checking diary.tsx file ==="
if [ -f "app/(tabs-user)/diary.tsx" ]; then
  echo "File exists. Showing context around lines 361-365:"
  sed -n '355,370p' "app/(tabs-user)/diary.tsx"
  echo ""
  echo "Showing context around line 380:"
  sed -n '375,385p' "app/(tabs-user)/diary.tsx"
else
  echo "File not found at app/(tabs-user)/diary.tsx"
  find . -name "diary.tsx" -type f
fi

Repository: safori-team/CARING-front

Length of output: 1300


🏁 Script executed:

#!/bin/bash
# Search for Icon component usage patterns and definition
echo "=== Searching for Icon/SvgIcon import and definition ==="
rg -n "type IconProps|interface IconProps" --type=ts --type=tsx -B2 -A10

echo ""
echo "=== Searching for Icon component export ==="
rg -n "export.*Icon" --type=ts --type=tsx | grep -E "(function|const|class)" | head -20

Repository: safori-team/CARING-front

Length of output: 242


🏁 Script executed:

#!/bin/bash
echo "=== SvgIcon.tsx component definition ==="
cat -n "./shared/ui/svg/SvgIcon.tsx"

echo ""
echo "=== icon.d.ts type definitions ==="
cat -n "./shared/ui/svg/icon.d.ts"

echo ""
echo "=== Icon import in diary.tsx ==="
rg -n "import.*Icon" "app/(tabs-user)/diary.tsx" -A2

Repository: safori-team/CARING-front

Length of output: 1409


🏁 Script executed:

#!/bin/bash
# Check for Icon/SvgIcon usage patterns in the entire codebase
echo "=== Icon component usage patterns in codebase ==="
rg -n "Icon\s+\w+=" --type=tsx | head -30

Repository: safori-team/CARING-front

Length of output: 162


🏁 Script executed:

#!/bin/bash
# Check Icon import in diary.tsx more carefully
echo "=== Icon import in diary.tsx ==="
head -50 "app/(tabs-user)/diary.tsx" | grep -n "Icon"

echo ""
echo "=== Check if there are multiple Icon imports ==="
rg -n "^import.*Icon" "app/(tabs-user)/diary.tsx"

echo ""
echo "=== Verify SvgProps type to understand full interface ==="
rg -n "SvgProps" "./shared/ui/svg/" -A5

Repository: safori-team/CARING-front

Length of output: 657


🏁 Script executed:

#!/bin/bash
# Let's verify how Icon is imported in diary.tsx to ensure it's the same component
echo "=== Full import statement context in diary.tsx ==="
head -40 "app/(tabs-user)/diary.tsx" | tail -20

Repository: safori-team/CARING-front

Length of output: 595


Icon 컴포넌트에 width/height props가 전달되지만 무시됩니다.

Icon 컴포넌트는 { name, size, onPress }만 받으므로, 여기서 전달하는 width={40} height={40}은 무시되어 아이콘이 의도한 크기로 렌더링되지 않습니다. Line 380의 width={20} height={20}도 동일한 문제입니다.

수정 방법

Line 361-365:

              <Icon
                name={recordingState.isRecording ? "Stop" : "Mic"}
-               width={40}
-               height={40}
+               size={40}
              />

Line 380:

-                   <Icon name="CheckIcon" width={20} height={20} />
+                   <Icon name="CheckIcon" size={20} />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Icon
name={recordingState.isRecording ? "Stop" : "Mic"}
width={40}
height={40}
/>
<Icon
name={recordingState.isRecording ? "Stop" : "Mic"}
size={40}
/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(tabs-user)/diary.tsx around lines 361 - 365, The Icon component is
being passed width and height props which are ignored because Icon only accepts
{ name, size, onPress }; update the usages where Icon is rendered (the Icon with
name computed via recordingState.isRecording and the smaller Icon at the later
usage) to pass a single numeric size prop (e.g., size={40} and size={20})
instead of width/height, or alternatively update the Icon component signature to
accept and map width/height into size; locate the Icon calls by the name prop
usage (name={recordingState.isRecording ? "Stop" : "Mic"}) and change to
size={40} (and the other Icon to size={20}) so the icons render at the intended
dimensions.

@jpark0506 jpark0506 merged commit b581a86 into dev Feb 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant