Skip to content

페이지 이동 시 지도 깜빡임 방지 - #251

Merged
onebone merged 5 commits into
developfrom
feat/249-map-flicker
Aug 9, 2026
Merged

onebone merged 5 commits into
developfrom
feat/249-map-flicker

Conversation

@onebone

@onebone onebone commented Aug 8, 2026 •

Copy link
Copy Markdown
Contributor

변경 내용

  • PLIMAP 지도를 라우트 전환 중에도 유지해 재마운트로 인한 깜빡임을 방지했습니다.
  • 핀 등록에서 현재 위치와 카메라 화면을 보존하고, 장소 목록 뒤에서 등록 지도를 미리 준비해 지도 선택 단계 전환 시 깜빡임을 제거했습니다.
  • 메인 지도가 가려진 동안 위치·방향 추적과 재생 리소스를 정리하고, 복귀 시 지도 상태를 복원했습니다.

관련 이슈

Closes #249

변경 사항

  • 새로운 기능 추가
  • 버그 수정
  • UI/UX 개선
  • 리팩토링
  • 문서 업데이트

테스트

  • 브라우저에서 정상 동작 확인

  • 기존 기능에 영향 없음 확인

  • PLIMAP → 핀 등록 장소 목록 → 지도 선택 전환에서 등록 지도가 재마운트되거나 로딩 화면을 노출하지 않는지 실제 Google Maps로 확인

  • 핀 등록 진입·복귀 시 현재 위치와 메인 지도 카메라 상태가 유지되는지 확인

  • npm run lint 통과 (오류 0건, 기존 Fast Refresh 경고 2건)

  • npm run build 통과 (기존 Lottie direct-eval 및 청크 크기 경고)

  • git diff --check 통과

  • clean-context adversarial review에서 P0–P3 지적 사항 없음

스크린샷 (UI 변경시)

체크리스트

  • 코드가 정상적으로 동작합니다
  • 새로운 에러나 경고가 없습니다
  • 필요시 문서를 업데이트했습니다
  • 코드 포맷팅을 실행했습니다 (pnpm format)
  • ESLint 검사를 통과했습니다 (pnpm lint:fix)

코드 품질 확인
PR 제출 전에 다음 명령어를 실행하여 코드 품질을 확인해주세요:

pnpm lint:fix
pnpm format

Summary by CodeRabbit

  • 새 기능
    • 경로와 표시 상태에 따라 지도를 지연 표시하고, 화면 전환 시 지도 위치를 저장·복원합니다.
    • 지도 가림 상태에서 현재 위치 추적과 YouTube 클립 재생을 자동으로 중지합니다.
    • 핀 등록 단계별 지도 중심, 핀 선택 및 현재 위치 처리를 개선했습니다.
    • 지도 이동과 현재 위치 변경 사항을 등록 화면에 연동합니다.
    • 앱 라우팅과 하단 내비게이션 구조를 정리했습니다.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e84290d-31ac-4ffe-bda9-89865efe078a

📥 Commits

Reviewing files that changed from the base of the PR and between 122e70a and 629911e.

📒 Files selected for processing (2)
  • src/features/map/hooks/useGoogleMap.ts
  • src/hooks/useYouTubeClipPlayer.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/features/map/hooks/useGoogleMap.ts
  • src/hooks/useYouTubeClipPlayer.ts

📝 Walkthrough

Walkthrough

지도 레이아웃을 라우트 기반 표시 모드로 재구성했다. 지도 뷰포트 캡처·복원과 위치 추적 제어를 추가했다. 지도 가림 상태에서 YouTube 재생을 중지한다. 핀 등록 단계는 현재 위치와 지도 뷰포트를 사용한다.

Changes

지도 표시 및 등록 흐름

Layer / File(s) Summary
지도 API와 위치 추적 제어
src/features/map/components/MapViewer.tsx, src/features/map/hooks/useGoogleMap.ts, src/features/map/hooks/useCurrentLocationMarker.ts
MapViewer가 위치 추적 비활성화 옵션과 뷰포트 캡처·복원 핸들을 노출한다. useGoogleMap은 현재 뷰포트를 읽고 저장하거나 복원한다. useCurrentLocationMarker는 추적 비활성화 시 위치 조회와 나침반 리스너를 정리한다.
지도 레이아웃과 가림 상태 처리
src/layouts/MapLayout.tsx, src/pages/MapPage.tsx, src/hooks/useYouTubeClipPlayer.ts, src/routes/index.tsx
MapLayout이 라우트별 지도 표시 모드, 현재 위치, 저장된 뷰포트를 관리한다. MapPage는 가림 전후에 뷰포트를 저장·복원하고 YouTube 재생을 중지한다. 인증된 라우트 구조에 지도와 하단 내비게이션 중첩을 적용한다.
핀 등록 위치와 단계별 지도 연동
src/layouts/PinRegistrationLayout.tsx, src/pages/PinRegisterEntryPage.tsx
핀 등록 단계가 현재 위치와 장소 좌표를 초기 중심 및 이동 대상으로 사용한다. 입력 단계에서는 지도 상호작용과 위치 추적을 비활성화한다. 장소 검색에는 계산된 현재 위치 오버라이드를 전달한다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MapLayout
  participant MapPage
  participant MapViewer
  participant useGoogleMap
  participant useYouTubeClipPlayer
  MapLayout->>MapPage: 가림 상태와 저장된 뷰포트 전달
  MapPage->>MapViewer: 현재 뷰포트 캡처 요청
  MapViewer->>useGoogleMap: captureViewport 호출
  useGoogleMap-->>MapPage: MapViewport 반환
  MapPage->>useYouTubeClipPlayer: 플레이어 비활성화 및 재생 중지
  MapLayout->>MapPage: 가림 해제와 저장된 뷰포트 전달
  MapPage->>MapViewer: 저장된 뷰포트 복원 요청
  MapViewer->>useGoogleMap: restoreViewport 호출
Loading

Possibly related issues

  • #249: 페이지 이동 시 지도 깜빡임을 줄이기 위해 MapLayout 아래에 관련 라우트 레이아웃을 재구성한다.
  • #67: 지도 뷰포트 추적과 복원 및 상호작용 변경이 이슈의 모바일 지도 탐색 범위와 관련된다.

Possibly related PRs

Suggested reviewers: jeonggyul

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 페이지 이동 중 지도 깜빡임 방지라는 주요 변경 사항을 명확하게 요약합니다.
Linked Issues check ✅ Passed 변경 사항은 이슈 #249의 지도 깜빡임 수정과 관련 레이아웃을 MapLayout 아래로 이동하는 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 라우팅 재구성, 뷰포트 복원, 위치 추적 및 YouTube 리소스 정리는 지도 깜빡임 방지 목표와 직접 관련됩니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/249-map-flicker

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.

@onebone
onebone marked this pull request as ready for review August 8, 2026 20:01
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

https://pr-251.plimap.kr

@onebone onebone added the enhancement New feature or request label Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (3)
src/features/map/hooks/useGoogleMap.ts (1)

323-337: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

restoreViewport에서 flyingCancelRef.current를 비우세요.

captureViewport는 취소 후 flyingCancelRef.current = null로 정리합니다. restoreViewport는 같은 정리를 하지 않습니다. 이미 취소된 콜백 참조가 남아 다음 flyTo 이전에 다시 호출될 수 있습니다. 동작 차이는 현재 없지만 두 경로의 정리 규칙을 같게 하세요.

♻️ 제안 수정
       flyingCancelRef.current?.();
+      flyingCancelRef.current = null;
       clearFlyingSuppression();
       clearCenterChangeSuppression();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/map/hooks/useGoogleMap.ts` around lines 323 - 337, Update
restoreViewport to set flyingCancelRef.current to null immediately after
invoking the current cancellation callback, matching the cleanup performed by
captureViewport. Keep the existing viewport restoration and suppression-clearing
behavior unchanged.
src/hooks/useYouTubeClipPlayer.ts (1)

312-324: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

비활성화 시 playingKey 상태를 초기화하세요.

비활성화 분기는 activeKeyRef.current만 null로 설정합니다. playingKey state는 이전 값을 유지합니다. 소비자는 재생이 멈춘 뒤에도 해당 핀을 재생 중으로 표시합니다.

현재는 src/pages/MapPage.tsx의 241-243행이 별도 effect로 stopClipPlayback()을 호출해 이를 보완합니다. 훅 내부에서 처리하면 이 보완 코드가 필요 없습니다.

♻️ 제안 수정
     if (!enabled) {
-      clearStopTimer();
-      activeKeyRef.current = null;
+      stop();
       destroyPlayer();
       hostRef.current?.remove();
       hostRef.current = null;
       return;
     }
 
     void ensurePlayer().catch(() => {
       // 미리 준비 실패해도 재생 시점에 다시 시도한다.
     });
-  }, [clearStopTimer, destroyPlayer, enabled, ensurePlayer]);
+  }, [destroyPlayer, enabled, ensurePlayer, stop]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useYouTubeClipPlayer.ts` around lines 312 - 324, Update the
!enabled branch in useYouTubeClipPlayer to reset the playingKey state to null
alongside activeKeyRef.current, ensuring consumers no longer see a clip as
playing after playback is disabled. Then remove the redundant MapPage effect
that calls stopClipPlayback solely to perform this reset.
src/pages/MapPage.tsx (1)

208-221: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

지도가 아직 준비되지 않으면 복원이 영구히 누락됩니다.

wasCoveredRef.current를 effect 시작 시점에 항상 갱신합니다. mapLoadStatus !== 'ready'여서 218행에서 return하면, 이후 mapLoadStatus가 'ready'로 바뀌어 effect가 다시 실행되어도 wasCovered가 이미 false이므로 restoreViewport가 호출되지 않습니다.

현재는 initialCenter가 최초 생성 시 중심을 잡아 주므로 영향이 작습니다. 복원 대기 상태를 별도 ref로 유지하면 이 경계 케이스가 사라집니다.

♻️ 제안 수정
   useLayoutEffect(() => {
     const wasCovered = wasCoveredRef.current;
     wasCoveredRef.current = isCovered;
 
     if (!wasCovered && isCovered) {
       const liveViewport = mapViewerRef.current?.captureViewport();
       if (liveViewport) onSaveViewport(liveViewport);
+      needsRestoreRef.current = true;
       return;
     }
 
-    if (!wasCovered || isCovered || !savedViewport || mapLoadStatus !== 'ready') return;
+    if (isCovered || !needsRestoreRef.current || !savedViewport || mapLoadStatus !== 'ready') {
+      return;
+    }
 
+    needsRestoreRef.current = false;
     mapViewerRef.current?.restoreViewport(savedViewport);
   }, [isCovered, mapLoadStatus, onSaveViewport, savedViewport]);

needsRestoreRef는 wasCoveredRef 옆에 useRef(false)로 선언하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/MapPage.tsx` around lines 208 - 221, MapPage의 useLayoutEffect에서 지도
로딩 전 복원이 누락되지 않도록 wasCoveredRef와 별도로 needsRestoreRef를 useRef(false)로 추가하세요. 저장된
뷰포트 복원이 필요한 조건이 충족되면 needsRestoreRef를 유지하고, mapLoadStatus가 ready가 된 뒤 해당 ref를
확인해 restoreViewport를 호출한 후 초기화하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/hooks/useYouTubeClipPlayer.ts`:
- Around line 219-223: 비활성화 분기의 직접적인 event.target.destroy() 호출을 destroyPlayer()
경로로 변경해 playerRef.current를 먼저 비우고 플레이어를 정리하세요. 이후 기존 오류 reject 및 return 동작은
유지하고, ensurePlayer()와 cleanup에서 파괴된 YT.Player 인스턴스를 재사용하거나 다시 destroy하지 않도록 하세요.

In `@src/routes/index.tsx`:
- Around line 79-81: Update the /app/pin/search route configuration under
MapLayout to override the inherited bottomNavItem with null, ensuring the search
overlay renders without the bottom navigation while leaving other MapLayout
child routes unchanged.

---

Nitpick comments:
In `@src/features/map/hooks/useGoogleMap.ts`:
- Around line 323-337: Update restoreViewport to set flyingCancelRef.current to
null immediately after invoking the current cancellation callback, matching the
cleanup performed by captureViewport. Keep the existing viewport restoration and
suppression-clearing behavior unchanged.

In `@src/hooks/useYouTubeClipPlayer.ts`:
- Around line 312-324: Update the !enabled branch in useYouTubeClipPlayer to
reset the playingKey state to null alongside activeKeyRef.current, ensuring
consumers no longer see a clip as playing after playback is disabled. Then
remove the redundant MapPage effect that calls stopClipPlayback solely to
perform this reset.

In `@src/pages/MapPage.tsx`:
- Around line 208-221: MapPage의 useLayoutEffect에서 지도 로딩 전 복원이 누락되지 않도록
wasCoveredRef와 별도로 needsRestoreRef를 useRef(false)로 추가하세요. 저장된 뷰포트 복원이 필요한 조건이
충족되면 needsRestoreRef를 유지하고, mapLoadStatus가 ready가 된 뒤 해당 ref를 확인해
restoreViewport를 호출한 후 초기화하세요.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 160c8ff5-985b-4eb1-9110-9e90cb729bd6

📥 Commits

Reviewing files that changed from the base of the PR and between 574c987 and 122e70a.

📒 Files selected for processing (9)
  • src/features/map/components/MapViewer.tsx
  • src/features/map/hooks/useCurrentLocationMarker.ts
  • src/features/map/hooks/useGoogleMap.ts
  • src/hooks/useYouTubeClipPlayer.ts
  • src/layouts/MapLayout.tsx
  • src/layouts/PinRegistrationLayout.tsx
  • src/pages/MapPage.tsx
  • src/pages/PinRegisterEntryPage.tsx
  • src/routes/index.tsx

Comment thread src/hooks/useYouTubeClipPlayer.ts
Comment thread src/routes/index.tsx
@onebone onebone self-assigned this Aug 9, 2026

This branch was successfully deployed

1 active and 1 inactive deployments
preview-maintenance — 629911e6 Deployed Aug 9, 2026 by onebone via cleanup #416
preview — 629911e6 Deployed Aug 9, 2026 by onebone via deploy #415
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

페이지 이동할 때 지도가 깜빡이는 이슈 수정

1 participant