Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
워크스루이 PR은 Android 13+ 알림 권한 요청 기반 구조와 여행 템플릿 추천/구독 API 연동을 통해 콘텐츠 추천 화면을 재구현합니다. 기존 스낵바 기반 피드백을 성공/중복 모달로 전환하고, 알림 구독 플로우를 추가합니다. 변경 사항콘텐츠 추천 및 알림 권한 통합
예상 코드 리뷰 난이도🎯 3 (Moderate) | ⏱️ ~25 분 관련 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 unit tests (beta)
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.
Actionable comments posted: 2
🤖 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
`@data/travel/src/main/java/com/yapp/ndgl/data/travel/repository/TravelTemplateRepository.kt`:
- Around line 105-106: The current catch maps CODE_ALREADY_SUBSCRIBED to
DuplicateSuggestedTemplateException.Reason.SELF_PENDING which conflates
subscription-duplicate with suggestion-duplicate; add a distinct enum value
(e.g., Reason.SUBSCRIPTION_DUPLICATE) to DuplicateSuggestedTemplateException and
change the throw in the block that checks CODE_ALREADY_SUBSCRIBED to throw a
DuplicateSuggestedTemplateException with that new reason and include the
original exception as the cause (pass the caught exception into the
DuplicateSuggestedTemplateException constructor) so callers can distinguish
subscription vs suggestion duplicates and inspect the root cause; update any
constructors/signatures of DuplicateSuggestedTemplateException to accept and
store the cause if needed.
In
`@feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.kt`:
- Around line 69-79: The call sites in requestNotificationOrNavigate that
force-cast context to Activity (e.g.,
ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, ... )
and context.startActivity(...)) can throw ClassCastException for non-Activity
Contexts; fix by safely obtaining an Activity at the start of
requestNotificationOrNavigate (e.g., val activity = context as? Activity) and
bail out or handle the no-Activity case (return or open settings via
context.applicationContext) if activity is null, then replace occurrences of
(context as Activity) and context.startActivity(...) with activity and
activity.startActivity(...), and use activity for permission rationale checks
and intent launching to avoid unsafe casts.
🪄 Autofix (Beta)
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: 939077ae-ab0a-4e93-8d73-319e0fed3857
📒 Files selected for processing (13)
app/src/main/AndroidManifest.xmlapp/src/main/java/com/yapp/ndgl/MainActivity.ktdata/travel/src/main/java/com/yapp/ndgl/data/travel/api/TravelTemplateApi.ktdata/travel/src/main/java/com/yapp/ndgl/data/travel/exception/DuplicateSuggestedTemplateException.ktdata/travel/src/main/java/com/yapp/ndgl/data/travel/model/SubscribeTemplateRequest.ktdata/travel/src/main/java/com/yapp/ndgl/data/travel/model/SuggestTemplateRequest.ktdata/travel/src/main/java/com/yapp/ndgl/data/travel/repository/TravelTemplateRepository.ktfeature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationContract.ktfeature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktfeature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationViewModel.ktfeature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/TravelThemeSection.ktfeature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/model/TravelTheme.ktfeature/content-recommendation/src/main/res/values/strings.xml
| fun requestNotificationOrNavigate() { | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||
| val hasPermission = ContextCompat.checkSelfPermission( | ||
| context, | ||
| Manifest.permission.POST_NOTIFICATIONS, | ||
| ) == PackageManager.PERMISSION_GRANTED | ||
|
|
||
| val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale( | ||
| context as Activity, | ||
| Manifest.permission.POST_NOTIFICATIONS, | ||
| ) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Line 77 강제 캐스팅 및 권한 rationale 호출 위치 확인
rg -n -C2 'context as Activity|shouldShowRequestPermissionRationale\(|LocalContext\.current' \
feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktRepository: NDGL-official/NDGL-android
Length of output: 570
🏁 Script executed:
# ContentRecommendationScreen.kt 파일 전체 크기와 함수 시그니처 확인
wc -l feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktRepository: NDGL-official/NDGL-android
Length of output: 194
🏁 Script executed:
# 함수 시그니처와 주변 context 확인
head -70 feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.kt | tail -20Repository: NDGL-official/NDGL-android
Length of output: 812
🏁 Script executed:
# LocalActivity 사용 가능성 확인
rg -l 'LocalActivity|androidx.activity' feature/content-recommendation/Repository: NDGL-official/NDGL-android
Length of output: 190
🏁 Script executed:
# 동일한 패턴(unsafe Activity cast) 확인
rg -n 'as Activity|as Context' feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktRepository: NDGL-official/NDGL-android
Length of output: 110
🏁 Script executed:
cat -n feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.kt | head -100Repository: NDGL-official/NDGL-android
Length of output: 4857
🏁 Script executed:
# 파일의 import 섹션 확인
head -50 feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktRepository: NDGL-official/NDGL-android
Length of output: 2383
🏁 Script executed:
# 권한 처리 관련 코드 전체 확인
sed -n '63,98p' feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.ktRepository: NDGL-official/NDGL-android
Length of output: 1346
LocalContext 강제 캐스팅으로 인한 크래시 위험
77번 줄의 context as Activity는 LocalContext.current가 ContextThemeWrapper 등의 non-Activity Context를 반환할 때 ClassCastException을 유발할 수 있습니다. 또한 85번 줄의 context.startActivity() 호출도 동일한 이유로 위험합니다.
안전 캐스팅으로 변경하거나, 함수 진입 초기에 Activity 존재 여부를 검증해야 합니다:
🔧 제안 수정안
fun requestNotificationOrNavigate() {
+ val activity = context as? Activity ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val hasPermission = ContextCompat.checkSelfPermission(
context,
Manifest.permission.POST_NOTIFICATIONS,
) == PackageManager.PERMISSION_GRANTED
val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(
- context as Activity,
+ activity,
Manifest.permission.POST_NOTIFICATIONS,
)
when {
hasPermission -> navigateBack()
shouldShowRationale -> {
context.startActivity(
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
},
)
navigateBack()
}
else -> notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
} else {
navigateBack()
}
}🤖 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
`@feature/content-recommendation/src/main/java/com/yapp/ndgl/feature/contentrecommendation/ContentRecommendationScreen.kt`
around lines 69 - 79, The call sites in requestNotificationOrNavigate that
force-cast context to Activity (e.g.,
ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, ... )
and context.startActivity(...)) can throw ClassCastException for non-Activity
Contexts; fix by safely obtaining an Activity at the start of
requestNotificationOrNavigate (e.g., val activity = context as? Activity) and
bail out or handle the no-Activity case (return or open settings via
context.applicationContext) if activity is null, then replace occurrences of
(context as Activity) and context.startActivity(...) with activity and
activity.startActivity(...), and use activity for permission rationale checks
and intent launching to avoid unsafe casts.
개요
연관 문서
디자인
변경사항
Summary by CodeRabbit
릴리스 노트
새 기능
개선 사항