Skip to content

feat: 네이티브 바텀탭 제거 → 단일 웹뷰 셸 + 앱 버전 브릿지#21

Open
seongwon030 wants to merge 5 commits into
mainfrom
feature/webview-shell-migration
Open

feat: 네이티브 바텀탭 제거 → 단일 웹뷰 셸 + 앱 버전 브릿지#21
seongwon030 wants to merge 5 commits into
mainfrom
feature/webview-shell-migration

Conversation

@seongwon030

@seongwon030 seongwon030 commented Jun 2, 2026

Copy link
Copy Markdown
Member

요약

홍보·알림 위치 ABCD 실험의 선결 조건인 웹 셸 이관의 RN 측 작업. 네이티브 바텀 탭바를 제거하고 홈 웹뷰를 단일 풀스크린 호스트로 만든다. 바텀 네비게이션(홈/구독/메뉴)은 이제 웹이 렌더한다.

변경

  • app/(tabs) 탭 레이아웃 및 네이티브 구독/메뉴 화면 제거 → app/index.tsx가 홈 웹뷰 단일 호스트
  • app/_layout.tsx Stack/anchor를 (tabs)index로, 동아리 상세·웹뷰 back 폴백을 /
  • ui/home/home-webview-screen.tsxREQUEST_APP_VERSION → APP_VERSION 핸들러 추가 (웹 메뉴 페이지 앱 버전 표시용)
  • ui/home/home-webview-screen.tsx 상세 뒤로가기 처리 추가 (단일 웹뷰 셸이 상세까지 인-웹뷰로 품게 되어 필요):
    • NAVIGATE_BACK 메시지 → webView.goBack() (상세 < 버튼)
    • Android 하드웨어 백: 웹뷰 히스토리 있으면 goBack, 없으면 기본 동작(종료)
    • iOS 엣지 스와이프 백 제스처 활성화 (allowsBackForwardNavigationGestures)
  • ui/subscribe/* 제거 (웹이 대체)

관련

  • 프론트엔드: Moadong/moadong #1631~#1634 (웹 바텀나브 + 구독/메뉴 페이지 + APP_VERSION 브릿지)

검증

  • ⚠️ 런타임(Expo 빌드) 확인 권장: 단일 웹뷰 부팅 + 바텀나브 전환 + 앱버전 왕복 + 상세 진입/뒤로가기(< 버튼·Android 하드웨어 백·iOS 엣지 스와이프)

Summary by CodeRabbit

  • New Features

    • 웹뷰에서 앱 버전 요청에 응답하도록 지원
    • 웹뷰에서 뒤로가기 명령 수신 시 웹뷰 내비게이션으로 처리
  • Refactor

    • 하단 탭 네비게이션 레이아웃 제거로 라우팅 진입점 변경
    • 구독(Subscribe) 관련 화면 및 관련 UI/훅 일괄 제거
    • 앱 시작 로직 및 스플래시 차단 조건 관련 동작 조정
  • Bug Fixes

    • 외부 링크 및 하드웨어 뒤로가기 처리 개선

- (tabs) 탭 레이아웃 및 구독/메뉴 네이티브 화면 제거, app/index.tsx로 홈 웹뷰 단일 호스트
- _layout Stack/anchor를 index로, 상세/웹뷰 back 폴백을 /로 변경
- home-webview-screen에 REQUEST_APP_VERSION→APP_VERSION 핸들러 추가
- ui/subscribe 제거(웹이 대체)
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

앱 루트 라우팅 앵커를 (tabs)에서 index로 변경하고, 스플래시 블로킹 조건을 preload의 settled 및 초기 경로로 판정하도록 수정했습니다. 기본 Home 컴포넌트명이 Home으로 바뀌었고, Home WebView에 NAVIGATE_BACK·REQUEST_APP_VERSION 메시지 처리, canGoBack 추적, 하드웨어 뒤로가기 및 외부 링크 처리 로직을 추가했습니다. 일부 폴백 라우트를 루트(/)로 변경했습니다.

변경사항

라우팅 구조 및 웹뷰/홈 변경

Layer / File(s) Summary
루트 레이아웃 라우팅 앵커 및 스플래시 판단
app/_layout.tsx
unstable_settings.anchor(tabs)에서 index로 변경하고, 스플래시 블로킹(shouldBlockSplash)을 homeWebViewPreloadSettledinitialPathnameRef.current 기준으로 계산하도록 수정했습니다.
홈 컴포넌트 내보내기 및 HomeWebView 메시지/뒤로가기 처리
app/index.tsx, ui/home/home-webview-screen.tsx
기본 내보내기 이름을 HomeTabHome으로 변경했고, WebView 메시지에 NAVIGATE_BACK·REQUEST_APP_VERSION 케이스를 추가, onNavigationStateChange로 canGoBack 추적, Android 하드웨어 뒤로가기 분기, 외부 링크를 앱 내부 라우팅으로 전환하는 onShouldStartLoadWithRequest 및 WebView prop 연결을 추가했습니다.
폴백 네비게이션 경로 업데이트
app/webview/[slug].tsx, ui/club-detail/club-detail-screen.tsx
뒤로 갈 수 없을 때의 폴백 라우트를 "/(tabs)/more"/"/(tabs)"에서 루트 경로 "/"로 변경했습니다.

Sequence Diagram

sequenceDiagram
  participant WebView as WebView (웹 컨텐츠)
  participant Home as HomeWebViewScreen
  participant Router as Router
  participant Back as BackHandler

  WebView->>Home: postMessage(type: NAVIGATE_BACK / REQUEST_APP_VERSION)
  Home->>Home: if NAVIGATE_BACK -> webViewRef.current.goBack()
  Home->>WebView: if REQUEST_APP_VERSION -> postMessage(APP_VERSION)
  Back->>Home: hardwareBackPress -> check canGoBackRef
  Home->>WebView: canGoBack ? webViewRef.current.goBack() : Router.push('/')
Loading

예상 코드 리뷰 노력

🎯 3 (Moderate) | ⏱️ ~20 minutes

관련 PR

추천 리뷰어

  • oesnuj
  • SeongHoonC
  • lepitaaar
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ 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 feature/webview-shell-migration

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.

- NAVIGATE_BACK 메시지 수신 시 webView.goBack() (상세 '<' 버튼)
- Android 하드웨어 백: 웹뷰 히스토리 있으면 goBack, 없으면 종료
- iOS 엣지 스와이프 백 제스처 활성화 (allowsBackForwardNavigationGestures)
@seongwon030 seongwon030 self-assigned this Jun 7, 2026
seongwon030 and others added 3 commits June 7, 2026 18:04
Resolve conflicts:
- ui/home/home-webview-screen.tsx: keep both canGoBackRef (Android back) and
  loadFailedRef (preload failure tracking); wire onNavigationStateChange together
  with the new handleError for onError/onHttpError
- app/(tabs)/_layout.tsx, app/(tabs)/more.tsx, ui/subscribe/{components/empty-state,subscribe-screen}.tsx:
  keep deletions (native tabs/subscribe removed in favor of single webview shell)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
onShouldStartLoadWithRequest로 moadong.com 외부 URL 탐색을 가로채
/webview/[slug] 화면으로 push — 개인정보처리방침(노션) 등 외부 링크에
네이티브 헤더와 뒤로가기 버튼이 표시됨

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- handleShouldStartLoadWithRequest: iOS는 navigationType === 'click'인
  경우(사용자 탭)만 외부 URL로 인터셉트. 초기 로드·서버 리다이렉트('other')는
  통과시켜 스플래시 중 잘못된 화면 전환 방지
- handleMessage NAVIGATE_WEBVIEW: loaded 상태 guard 추가, 첫 로드 완료 전
  웹 페이지의 navigation 메시지 무시
- _layout.tsx: initialPathnameRef로 초기 경로 캡처, preload 중 pathname 변경에
  무관하게 homeWebViewPreloadSettled 조건 유지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/home/home-webview-screen.tsx (1)

92-102: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

handleMessage dependency array에 loaded 추가 필요.

Line 92에서 loaded 상태를 참조하지만, Line 119의 handleMessage 콜백 dependency array에 loaded가 누락되었습니다. 이는 React hooks exhaustive-deps 규칙을 위반하며, stale closure로 인해 loaded 값이 오래된 값으로 고정될 수 있습니다.

🔧 수정 제안
   },
-  [subscribedClubIds, toggleSubscribe, sendMessage, sendSubscribeState, router],
+  [subscribedClubIds, toggleSubscribe, sendMessage, sendSubscribeState, router, loaded],
 );

Line 119의 dependency array에 loaded를 추가하세요.

🤖 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 `@ui/home/home-webview-screen.tsx` around lines 92 - 102, The handleMessage
callback references the loaded state but its hook dependency array does not
include loaded, which can cause a stale closure; update the useCallback (or
wherever handleMessage is defined) to include loaded in its dependency array so
handleMessage always sees the current loaded value—look for the handleMessage
function and the dependency array near its definition and add loaded alongside
existing dependencies (e.g., router and payload-related dependencies).
🤖 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.

Outside diff comments:
In `@ui/home/home-webview-screen.tsx`:
- Around line 92-102: The handleMessage callback references the loaded state but
its hook dependency array does not include loaded, which can cause a stale
closure; update the useCallback (or wherever handleMessage is defined) to
include loaded in its dependency array so handleMessage always sees the current
loaded value—look for the handleMessage function and the dependency array near
its definition and add loaded alongside existing dependencies (e.g., router and
payload-related dependencies).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d3c543bf-90ba-41b4-995c-f504f2039b9b

📥 Commits

Reviewing files that changed from the base of the PR and between 8d3eefd and 92005c9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • app/_layout.tsx
  • ui/home/home-webview-screen.tsx

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