Skip to content

Feat/#95: ActionSheet 기반 카메라/갤러리 사진 선택 기능 추가#97

Merged
DongChyeon merged 10 commits into
developfrom
feature/#95-upload-photo-camera-gallery
Apr 26, 2026
Merged

Feat/#95: ActionSheet 기반 카메라/갤러리 사진 선택 기능 추가#97
DongChyeon merged 10 commits into
developfrom
feature/#95-upload-photo-camera-gallery

Conversation

@DongChyeon
Copy link
Copy Markdown
Member

@DongChyeon DongChyeon commented Apr 26, 2026

🛠 Related issue

closed #95

어떤 변경사항이 있었나요?

  • 🐞 BugFix Something isn't working
  • 🎨 Design Markup & styling
  • 📃 Docs Documentation writing and editing (README.md, etc.)
  • ✨ Feature Feature
  • 🔨 Refactor Code refactoring
  • ⚙️ Setting Development environment setup
  • ✅ Test Test related (Junit, etc.)

✅ CheckPoint

  • PR 컨벤션에 맞게 작성했습니다. (필수)
  • merge할 브랜치의 위치를 확인해 주세요(main❌/develop⭕) (필수)
  • Approve된 PR은 assigner가 머지하고, 수정 요청이 온 경우 수정 후 다시 push를 합니다. (필수)
  • BugFix의 경우, 버그의 원인을 파악하였습니다. (선택)

✏️ Work Description

image - `ActionSheet` 컴포넌트 신규 추가 (아이콘 + 텍스트 구성, `BuyOrNotBottomSheet` 기반) - `BuyOrNotIcons`에 `Gallery` 아이콘 추가 및 `ic_gallery` 내부 흰색 영역 evenOdd 클리핑 처리 - `ActionItem`, `ActionSheet` 공용 API KDoc 작성 - 업로드 화면 카메라 아이콘 터치 시 ActionSheet로 카메라/갤러리 선택 분기 - 카메라: CAMERA 권한 확인 → 없으면 요청 → MediaStore URI 생성 후 촬영 - 갤러리: 기존 `PickMultipleVisualMedia` 동작 유지 - 촬영 사진을 MediaStore로 저장 (API 29+ `Pictures/BuyOrNot` 폴더, 갤러리 자동 노출) - 촬영 취소 시 MediaStore 빈 항목 자동 삭제

😅 Uncompleted Tasks

  • N/A

📢 To Reviewers

  • ActionSheetOptionSheet와 동일한 BuyOrNotBottomSheet 기반이나, 선택 상태 없이 액션 실행에 특화된 별도 컴포넌트입니다.
  • 카메라 저장은 FileProvider 대신 MediaStore를 사용해 별도 후처리 없이 갤러리에 자동 노출됩니다.
  • showPhotoPickerSheet 상태는 기존 showCategorySheet 패턴과 동일하게 ViewModel에서 관리합니다.

📃 RCA 룰

  • R: 꼭 반영해 주세요. 적극적으로 고려해 주세요. (Request changes)
  • C: 웬만하면 반영해 주세요. (Comment)
  • A: 반영해도 좋고 넘어가도 좋습니다. 그냥 사소한 의견입니다. (Approve)

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 카메라를 통한 사진 촬영 기능이 추가되었습니다.
    • 사진 선택 시 카메라 또는 갤러리 중에서 선택할 수 있는 옵션이 제공됩니다.
  • 스타일

    • 상품 이미지 영역에 테두리 스타일이 추가되었습니다.

DongChyeon and others added 9 commits April 26, 2026 15:13
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- UploadUiState에 showPhotoPickerSheet 필드 추가
- UploadIntent에 UpdatePhotoPickerSheetVisibility 클래스 추가
- UploadViewModel에 핸들러 추가로 exhaustive when 조건 만족

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

Warning

Rate limit exceeded

@DongChyeon has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 50 minutes and 40 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 50 minutes and 40 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 922e77bf-2e2c-429b-9b72-2a88e47909be

📥 Commits

Reviewing files that changed from the base of the PR and between 4faeec5 and 92e0552.

📒 Files selected for processing (1)
  • feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt

Walkthrough

이 PR은 사진 선택 옵션을 확장하는 기능을 추가합니다. 카메라 권한을 선언하고, 하단 시트 기반 액션 시트 컴포넌트를 도입하며, 갤러리 아이콘을 추가하고, 업로드 화면을 수정하여 카메라로 촬영하거나 갤러리에서 선택하는 두 가지 옵션을 제공합니다.

Changes

Cohort / File(s) Summary
Manifest 및 권한
app/src/main/AndroidManifest.xml
CAMERA 런타임 권한을 앱 매니페스트에 추가합니다.
디자인 시스템 아이콘
core/designsystem/src/main/java/.../BuyOrNotIcons.kt, core/designsystem/src/main/res/drawable/ic_gallery.xml
갤러리 기능을 위한 새 아이콘 리소스(Gallery)를 정의하고 벡터 드로어블(20dp)을 추가합니다.
디자인 시스템 컴포넌트
core/designsystem/src/main/java/.../ActionSheet.kt
아이콘, 라벨, 클릭 핸들러를 포함한 액션 항목을 렌더링하는 새로운 ActionSheet 하단 시트 컴포넌트를 정의합니다. 항목 클릭 시 콜백을 실행한 후 시트를 자동으로 닫습니다.
피드 카드 UI
core/designsystem/src/main/java/.../FeedCard.kt
클립된 이미지 주변에 1dp 회색 테두리와 16.dp 모서리 반경을 추가합니다.
업로드 상태 관리
feature/upload/src/main/java/.../UploadContract.kt, feature/upload/src/main/java/.../UploadViewModel.kt
UI 상태에 showPhotoPickerSheet 플래그를 추가하고, 시트 가시성을 제어하기 위한 새 인텐트 UpdatePhotoPickerSheetVisibility를 정의합니다.
업로드 화면 UI
feature/upload/src/main/java/.../UploadScreen.kt
ActionSheet를 통해 카메라와 갤러리 옵션을 선택할 수 있도록 사진 선택 플로우를 변경합니다. 카메라 선택 시 권한 검사, MediaStore 사전 삽입, TakePicture 계약 실행, 실패 시 정리를 수행합니다.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UploadScreen
    participant ActionSheet
    participant PermissionManager
    participant MediaStore
    participant Camera
    participant UploadViewModel

    User->>UploadScreen: 카메라 아이콘 클릭
    UploadScreen->>UploadViewModel: UpdatePhotoPickerSheetVisibility(true)
    UploadViewModel->>UploadScreen: showPhotoPickerSheet = true
    UploadScreen->>ActionSheet: ActionSheet 표시
    
    alt 카메라 선택
        User->>ActionSheet: 카메라 옵션 선택
        ActionSheet->>UploadScreen: 카메라 콜백 실행
        UploadScreen->>PermissionManager: CAMERA 권한 검사
        
        alt 권한 승인됨
            PermissionManager->>MediaStore: 이미지 파일 사전 생성
            MediaStore-->>UploadScreen: photoUri 반환
            UploadScreen->>Camera: TakePicture 계약 실행
            Camera->>Camera: 사용자 사진 촬영
            Camera-->>UploadScreen: 촬영 결과
            UploadScreen->>UploadViewModel: AddImages(캡처된 이미지)
        else 권한 거부됨
            PermissionManager-->>UploadScreen: 권한 거부
            UploadScreen->>MediaStore: photoUri 삭제
        end
    else 갤러리 선택
        User->>ActionSheet: 갤러리 옵션 선택
        ActionSheet->>UploadScreen: 갤러리 콜백 실행
        UploadScreen->>UploadViewModel: AddImages(선택된 이미지)
    end
    
    UploadScreen->>UploadViewModel: UpdatePhotoPickerSheetVisibility(false)
    UploadViewModel->>UploadScreen: showPhotoPickerSheet = false
    UploadScreen->>ActionSheet: ActionSheet 닫음
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

  • PR #90: 업로드 기능(UploadScreen, UploadViewModel)의 이미지 선택 동작과 UI를 수정하여 카메라/갤러리 플로우를 변경합니다.
  • PR #62: 업로드 기능(UploadContract, UploadScreen, UploadViewModel)과 앱 매니페스트 권한을 동일하게 수정합니다.
  • PR #25: 동일한 파일 core/designsystem/src/main/java/.../FeedCard.kt를 수정하여 이미지 스타일 변경을 다룹니다.

Suggested labels

✨ FEAT, 💪 동현동현동현

Suggested reviewers

  • Imagine-Choi
🚥 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
Linked Issues check ✅ Passed 모든 연결된 이슈 #95의 요구사항이 충족되었습니다: ActionSheet 기반 옵션 제공, 카메라 촬영 기능 구현, 갤러리 선택 플로우 유지.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #95의 범위 내에 있습니다. FeedCard 테두리 추가는 ActionSheet 컴포넌트와 함께 디자인 시스템 개선으로 관련성이 있습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 목표를 정확하게 반영하고 있습니다. ActionSheet 기반의 카메라/갤러리 사진 선택 기능이 이 PR의 핵심 변경사항이며, 제목이 이를 명확하게 전달합니다.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#95-upload-photo-camera-gallery

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.

@DongChyeon DongChyeon self-assigned this Apr 26, 2026
@DongChyeon DongChyeon requested a review from Imagine-Choi April 26, 2026 07:14
@DongChyeon DongChyeon added ✨ FEAT 기능 개발 (애매하면 기능 개발로 두도록 하자) 💪 동현동현동현 labels Apr 26, 2026
@DongChyeon DongChyeon changed the title feat/#95: ActionSheet 기반 카메라/갤러리 사진 선택 기능 추가 Feat/#95: ActionSheet 기반 카메라/갤러리 사진 선택 기능 추가 Apr 26, 2026
Copy link
Copy Markdown

@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 (5)
feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt (1)

181-219: insertPhotoUri() / 권한 처리 로직을 추출해 중복 제거 권장.

카메라 클릭 핸들러(Line 188-203)와 권한 콜백(Line 145-156)에서 "권한 확인 → URI 삽입 → 런처 launch" 흐름이 거의 동일하게 반복됩니다. 한 함수로 추출하면 향후 권한 거부/실패 처리(위 코멘트)도 한 곳에서 관리할 수 있습니다.

♻️ 제안 수정안 스케치
+    val launchCamera: () -> Unit = {
+        val uri = insertPhotoUri()
+        if (uri != null) {
+            photoUri = uri
+            cameraLauncher.launch(uri)
+        }
+    }
...
-                            if (hasCameraPermission) {
-                                val uri = insertPhotoUri()
-                                if (uri != null) {
-                                    photoUri = uri
-                                    cameraLauncher.launch(uri)
-                                }
-                            } else {
-                                cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
-                            }
+                            if (hasCameraPermission) launchCamera()
+                            else cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt`
around lines 181 - 219, The camera handling flow (permission check →
insertPhotoUri() → set photoUri → cameraLauncher.launch) is duplicated between
the camera click handler and the cameraPermissionLauncher callback; extract that
logic into a single helper (e.g., ensureCameraUriAndLaunch or
openCameraWithPermission) that: checks CAMERA permission, calls
insertPhotoUri(), sets photoUri, and invokes cameraLauncher.launch(uri) or
returns/handles failure; then replace both the onClick lambda in the ActionItem
and the cameraPermissionLauncher callback to call this helper so all
permission-failure and URI-failure handling is centralized.
core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/ActionSheet.kt (2)

116-137: Preview 한계 안내(선택) — 모달 시트 미렌더 가능성.

ActionSheet은 내부적으로 ModalBottomSheet 기반의 BuyOrNotBottomSheet를 사용하므로, @Preview에서는 시트 내용이 그려지지 않을 수 있습니다. 디자인 검토용으로는 ActionItemRow만 따로 미리보는 보조 Preview를 추가하면 더 유용합니다.

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

In
`@core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/ActionSheet.kt`
around lines 116 - 137, ActionSheetPreview may not render the modal bottom sheet
because ActionSheet uses BuyOrNotBottomSheet/ModalBottomSheet; add a separate
Preview for the row component so designers can see the content: create a new
`@Preview` composable that wraps a sample ActionItem (use the ActionItem data
class and BuyOrNotIcons) and calls the ActionItemRow (or the exact row
composable used inside ActionSheet) inside BuyOrNotTheme; keep
ActionSheetPreview as-is (or annotate it with a note) but ensure the new preview
references ActionItemRow, ActionItem, and BuyOrNotIcons so the row UI renders in
the preview.

69-81: items(actions) 확장 함수로 단순화 가능.

items(count = actions.size, key = { it })에서 it은 인덱스(Int)이므로 사실상 키를 지정하지 않은 것과 동일합니다. androidx.compose.foundation.lazy.items 확장을 사용하면 가독성도 좋아지고, 필요시 key로 안정적인 식별자(text 등)를 주기에도 명확합니다.

♻️ 제안 수정안
-import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
...
-            items(
-                count = actions.size,
-                key = { it },
-            ) { index ->
-                val action = actions[index]
-                ActionItemRow(
+            items(
+                items = actions,
+                key = { it.text },
+            ) { action ->
+                ActionItemRow(
                     item = action,
                     onClick = {
                         action.onClick()
                         hideSheet()
                     },
                 )
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/ActionSheet.kt`
around lines 69 - 81, Replace the indexed items usage with the
androidx.compose.foundation.lazy.items extension to simplify and clarify the
loop in ActionSheet.kt: instead of items(count = actions.size, key = { it }) {
index -> val action = actions[index] ... }, call items(actions, key = { action
-> <stableId> }) { action -> ActionItemRow(item = action, onClick = {
action.onClick(); hideSheet() }) }, using a stable identifier for the key (for
example action.id or action.text) rather than the index.
feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadViewModel.kt (1)

69-78: NavigateBack 처리 시 showPhotoPickerSheet도 함께 초기화 권장.

기존 NavigateBackshowExitDialog/showCategorySheet를 닫아주지만, 새로 추가된 showPhotoPickerSheet는 초기화되지 않습니다. 시트가 열려 있는 상태에서 뒤로가기 흐름이 트리거되면 상태가 불일치할 수 있으니 일관성을 위해 함께 닫아주는 것이 좋습니다.

♻️ 제안 수정안
             UploadIntent.NavigateBack -> {
                 updateState {
-                    it.copy(showExitDialog = false, showCategorySheet = false)
+                    it.copy(
+                        showExitDialog = false,
+                        showCategorySheet = false,
+                        showPhotoPickerSheet = false,
+                    )
                 }
                 sendSideEffect(UploadSideEffect.NavigateBack)
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadViewModel.kt`
around lines 69 - 78, 현재 UploadIntent.NavigateBack 처리에서 updateState가
showExitDialog와 showCategorySheet만 false로 설정하고 있어 showPhotoPickerSheet가 닫히지 않는
문제입니다; UploadIntent.NavigateBack 분기에서 호출하는 updateState 블록에 showPhotoPickerSheet
= false를 추가하여 상태를 일관되게 초기화하고 그 후 기존
sendSideEffect(UploadSideEffect.NavigateBack)를 그대로 호출하도록 수정하세요.
app/src/main/AndroidManifest.xml (1)

6-6: <uses-feature> 선언 누락 — 카메라 미탑재 기기 노출 차단 위험.

android.permission.CAMERA를 선언하면 Google Play가 암묵적으로 android.hardware.camera 기능을 요구하는 것으로 간주하여, 카메라가 없는 기기(태블릿/Chromebook 등)에서 앱이 설치 목록에 노출되지 않을 수 있습니다. 본 기능은 갤러리 선택 옵션으로 대체 가능하므로 required="false"로 선언해 두는 것이 안전합니다.

📱 제안 수정안
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-feature
+        android:name="android.hardware.camera"
+        android:required="false" />
     <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/AndroidManifest.xml` at line 6, 현재 AndroidManifest에
android.permission.CAMERA만 선언되어 있어 Google Play가 암묵적으로 카메라 하드웨어를 요구하는 것으로 해석될 수
있으니, 앱이 카메라 미탑재 기기에도 노출되도록 manifest에 uses-feature 요소(<uses-feature
android:name="android.hardware.camera" android:required="false"/>)를 추가하여 카메라를
선택적 기능으로 표시하고 기존의 <uses-permission android:name="android.permission.CAMERA"/>
선언은 유지하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt`:
- Around line 112-156: The photoUri stored with remember {
mutableStateOf<Uri?>(null) } can be lost across process death; change storage to
survive recreation by using rememberSaveable (serialize Uri via
Uri.toString()/Uri.parse) or move the pending URI into the UploadViewModel
(e.g., pendingCameraUri) so the camera flow keeps the URI between process
restarts; update places referencing photoUri (cameraPermissionLauncher callback
where insertPhotoUri() sets it, and cameraLauncher callback where
viewModel.handleIntent(UploadIntent.AddImages(listOf(it))) or
contentResolver.delete(it, ... ) is called) to use the new saved/restored value
consistently.
- Around line 145-156: The permission launcher (cameraPermissionLauncher)
silently ignores both denied permissions and insertPhotoUri() returning null, so
add user feedback and guidance: when granted == false show a Snackbar (or
dialog) informing the user that camera permission is required, and if
shouldShowRequestPermissionRationale indicates permanent denial, provide an
option to open app settings; likewise, when insertPhotoUri() returns null (both
inside cameraPermissionLauncher and the onClick handler where insertPhotoUri()
is called) show an error Snackbar explaining the failure to create the photo URI
and suggest retry/settings; use the existing cameraLauncher.launch(uri) flow
unchanged when uri is non-null and reuse a shared helper to show Snackbars to
avoid duplication.

---

Nitpick comments:
In `@app/src/main/AndroidManifest.xml`:
- Line 6: 현재 AndroidManifest에 android.permission.CAMERA만 선언되어 있어 Google Play가
암묵적으로 카메라 하드웨어를 요구하는 것으로 해석될 수 있으니, 앱이 카메라 미탑재 기기에도 노출되도록 manifest에 uses-feature
요소(<uses-feature android:name="android.hardware.camera"
android:required="false"/>)를 추가하여 카메라를 선택적 기능으로 표시하고 기존의 <uses-permission
android:name="android.permission.CAMERA"/> 선언은 유지하세요.

In
`@core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/ActionSheet.kt`:
- Around line 116-137: ActionSheetPreview may not render the modal bottom sheet
because ActionSheet uses BuyOrNotBottomSheet/ModalBottomSheet; add a separate
Preview for the row component so designers can see the content: create a new
`@Preview` composable that wraps a sample ActionItem (use the ActionItem data
class and BuyOrNotIcons) and calls the ActionItemRow (or the exact row
composable used inside ActionSheet) inside BuyOrNotTheme; keep
ActionSheetPreview as-is (or annotate it with a note) but ensure the new preview
references ActionItemRow, ActionItem, and BuyOrNotIcons so the row UI renders in
the preview.
- Around line 69-81: Replace the indexed items usage with the
androidx.compose.foundation.lazy.items extension to simplify and clarify the
loop in ActionSheet.kt: instead of items(count = actions.size, key = { it }) {
index -> val action = actions[index] ... }, call items(actions, key = { action
-> <stableId> }) { action -> ActionItemRow(item = action, onClick = {
action.onClick(); hideSheet() }) }, using a stable identifier for the key (for
example action.id or action.text) rather than the index.

In
`@feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt`:
- Around line 181-219: The camera handling flow (permission check →
insertPhotoUri() → set photoUri → cameraLauncher.launch) is duplicated between
the camera click handler and the cameraPermissionLauncher callback; extract that
logic into a single helper (e.g., ensureCameraUriAndLaunch or
openCameraWithPermission) that: checks CAMERA permission, calls
insertPhotoUri(), sets photoUri, and invokes cameraLauncher.launch(uri) or
returns/handles failure; then replace both the onClick lambda in the ActionItem
and the cameraPermissionLauncher callback to call this helper so all
permission-failure and URI-failure handling is centralized.

In
`@feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadViewModel.kt`:
- Around line 69-78: 현재 UploadIntent.NavigateBack 처리에서 updateState가
showExitDialog와 showCategorySheet만 false로 설정하고 있어 showPhotoPickerSheet가 닫히지 않는
문제입니다; UploadIntent.NavigateBack 분기에서 호출하는 updateState 블록에 showPhotoPickerSheet
= false를 추가하여 상태를 일관되게 초기화하고 그 후 기존
sendSideEffect(UploadSideEffect.NavigateBack)를 그대로 호출하도록 수정하세요.
🪄 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.yml

Review profile: CHILL

Plan: Pro

Run ID: f6e1704b-c591-4893-bd44-ba8c8b3fe39c

📥 Commits

Reviewing files that changed from the base of the PR and between 4573bfb and 4faeec5.

📒 Files selected for processing (8)
  • app/src/main/AndroidManifest.xml
  • core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/ActionSheet.kt
  • core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/components/FeedCard.kt
  • core/designsystem/src/main/java/com/sseotdabwa/buyornot/core/designsystem/icon/BuyOrNotIcons.kt
  • core/designsystem/src/main/res/drawable/ic_gallery.xml
  • feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadContract.kt
  • feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadScreen.kt
  • feature/upload/src/main/java/com/sseotdabwa/buyornot/feature/upload/ui/UploadViewModel.kt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@DongChyeon DongChyeon merged commit 227f05d into develop Apr 26, 2026
2 checks passed
@DongChyeon DongChyeon deleted the feature/#95-upload-photo-camera-gallery branch April 26, 2026 07:23
@coderabbitai coderabbitai Bot mentioned this pull request May 5, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ FEAT 기능 개발 (애매하면 기능 개발로 두도록 하자) 💪 동현동현동현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feature - 업로드 화면 카메라 선택 시 촬영/갤러리 선택 옵션 추가

1 participant