release 1.6.0#27
Conversation
- (tabs) 탭 레이아웃 및 구독/메뉴 네이티브 화면 제거, app/index.tsx로 홈 웹뷰 단일 호스트 - _layout Stack/anchor를 index로, 상세/웹뷰 back 폴백을 /로 변경 - home-webview-screen에 REQUEST_APP_VERSION→APP_VERSION 핸들러 추가 - ui/subscribe 제거(웹이 대체)
- NAVIGATE_BACK 메시지 수신 시 webView.goBack() (상세 '<' 버튼) - Android 하드웨어 백: 웹뷰 히스토리 있으면 goBack, 없으면 종료 - iOS 엣지 스와이프 백 제스처 활성화 (allowsBackForwardNavigationGestures)
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>
feat: 네이티브 바텀탭 제거 → 단일 웹뷰 셸 + 앱 버전 브릿지
- NAVIGATE_WEBVIEW 브릿지 payload에 clubId(ObjectId) 필드 추가 - ClubDetailScreen에서 slug 대신 ObjectId로 isSubscribed 조회하여 is_subscribed 초기값 항상 false 버그 수정 - HomeWebViewScreen SHARE 브릿지 메시지 처리 추가 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
feat: 웹뷰 셸 마이그레이션 — NAVIGATE_WEBVIEW clubId 연동 및 브릿지 보완
개요이 PR은 네이티브 바텀 탭 네비게이션을 제거하고 웹뷰 중심의 네비게이션 모델로 마이그레이션합니다. 루트 레이아웃 초기화, 스플래시 제어, 웹뷰 메시지 프로토콜을 재구성하며 플랫폼 설정 파일의 버전 정보를 1.6.0으로 업데이트합니다. 변경 사항웹뷰 기반 네비게이션 구조 변경
예상 코드 리뷰 시간🎯 4 (복잡함) | ⏱️ ~45분 관련 가능성 있는 PR
추천 검토자
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed due to a network error. 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. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
ui/club-detail/club-detail-screen.tsx (1)
81-97:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
handleSubscribeToggle에서lookupId대신id를 사용하여 일관성이 없습니다.URI 생성(line 41-43)과
subscribed계산(line 48-51)에서는lookupId를 사용하여objectId를 우선시하도록 수정되었지만,handleSubscribeToggle함수는 여전히id를 직접 사용합니다. 이로 인해 구독 토글 시 잘못된 ID로 동작할 수 있습니다.🐛 수정 제안
const handleSubscribeToggle = async () => { - if (id && typeof id === "string") { - const wasSubscribed = isSubscribed(id); + const lookupId = typeof objectId === 'string' ? objectId : id; + if (lookupId && typeof lookupId === "string") { + const wasSubscribed = isSubscribed(lookupId); trackEvent(USER_EVENT.SUBSCRIBE_BUTTON_CLICKED, { clubName: name, subscribed: !wasSubscribed, from: "club_detail", url: "app://moadong/club", }); - const result = await toggleSubscribe(id); + const result = await toggleSubscribe(lookupId); if (result.needsPermission) { setShowPermissionDialog(true); } } };🤖 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/club-detail/club-detail-screen.tsx` around lines 81 - 97, The handler uses id directly causing inconsistency with earlier logic that prefers lookupId (which prioritizes objectId); update handleSubscribeToggle to use lookupId everywhere: change the guard to if (lookupId && typeof lookupId === "string"), compute wasSubscribed = isSubscribed(lookupId), and call toggleSubscribe(lookupId); keep the existing trackEvent call but ensure it uses the same subscribed value (i.e., subscribed: !wasSubscribed). This makes handleSubscribeToggle consistent with the URI/subscribed calculations that rely on lookupId.ui/home/home-webview-screen.tsx (1)
119-124:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
loaded의존성이handleMessageuseCallback에서 누락되었습니다.Line 92에서
loaded상태를 사용하지만 dependency array (line 123)에 포함되어 있지 않습니다. 이로 인해loaded가true로 변경된 후에도 오래된false값을 참조할 수 있어NAVIGATE_WEBVIEW메시지가 무시될 수 있습니다.🐛 수정 제안
- }, [subscribedClubIds, toggleSubscribe, sendMessage, sendSubscribeState, router]); + }, [subscribedClubIds, toggleSubscribe, sendMessage, sendSubscribeState, router, 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 119 - 124, handleMessage useCallback currently reads the loaded state but doesn't list loaded in its dependency array, so update the dependency array for the handleMessage callback (the useCallback that references loaded and handles NAVIGATE_WEBVIEW) to include loaded alongside subscribedClubIds, toggleSubscribe, sendMessage, sendSubscribeState, and router to ensure the callback sees latest loaded value.
🤖 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/club-detail/club-detail-screen.tsx`:
- Around line 81-97: The handler uses id directly causing inconsistency with
earlier logic that prefers lookupId (which prioritizes objectId); update
handleSubscribeToggle to use lookupId everywhere: change the guard to if
(lookupId && typeof lookupId === "string"), compute wasSubscribed =
isSubscribed(lookupId), and call toggleSubscribe(lookupId); keep the existing
trackEvent call but ensure it uses the same subscribed value (i.e., subscribed:
!wasSubscribed). This makes handleSubscribeToggle consistent with the
URI/subscribed calculations that rely on lookupId.
In `@ui/home/home-webview-screen.tsx`:
- Around line 119-124: handleMessage useCallback currently reads the loaded
state but doesn't list loaded in its dependency array, so update the dependency
array for the handleMessage callback (the useCallback that references loaded and
handles NAVIGATE_WEBVIEW) to include loaded alongside subscribedClubIds,
toggleSubscribe, sendMessage, sendSubscribeState, and router to ensure the
callback sees latest loaded value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c6b73fbe-5aab-4d21-bb54-57e7b68031d0
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (21)
app.jsonapp/(tabs)/_layout.tsxapp/(tabs)/explore.tsxapp/(tabs)/index.tsx.backupapp/(tabs)/more.tsxapp/_layout.tsxapp/index.tsxapp/webview/[slug].tsxhooks/use-webview-message-handler.tsios/app.xcodeproj/project.pbxprojios/app/Info.plisttypes/webview-message.types.tsui/club-detail/club-detail-screen.tsxui/home/home-webview-screen.tsxui/subscribe/components/empty-state.tsxui/subscribe/components/index.tsui/subscribe/components/subscribed-club-list.tsxui/subscribe/hook/index.tsui/subscribe/hook/use-subscribe-screen.tsui/subscribe/index.tsui/subscribe/subscribe-screen.tsx
💤 Files with no reviewable changes (11)
- ui/subscribe/components/subscribed-club-list.tsx
- app/(tabs)/more.tsx
- app/(tabs)/index.tsx.backup
- ui/subscribe/hook/index.ts
- ui/subscribe/components/empty-state.tsx
- ui/subscribe/components/index.ts
- ui/subscribe/subscribe-screen.tsx
- ui/subscribe/index.ts
- app/(tabs)/_layout.tsx
- app/(tabs)/explore.tsx
- ui/subscribe/hook/use-subscribe-screen.ts
Summary
Validation
Summary by CodeRabbit
릴리스 노트
신기능
개선사항
Chores