-
Notifications
You must be signed in to change notification settings - Fork 1
갤러리 사진 선택 & 재촬영 기능 구현 #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
@coderabbitai review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In
`@feature/task-certification/src/main/java/com/twix/task_certification/component/CameraControlBar.kt`:
- Around line 84-111: The Image composables in CameraControlBar (the gallery,
shutter, and toggle Image elements) use contentDescription = null which breaks
accessibility; add localized string resources (camera_gallery_button,
camera_capture_button, camera_toggle_button, camera_refresh_button) to
strings.xml and set each Image's contentDescription to the appropriate string
via stringResource(R.string.<name>), e.g., use
stringResource(R.string.camera_gallery_button) for the Image tied to
onClickGallery, stringResource(R.string.camera_capture_button) for the shutter
that calls onCaptureClick, and stringResource(R.string.camera_toggle_button) for
the onToggleCameraClick Image, ensuring all interactive icons provide
descriptive contentDescriptions for screen readers.
- Line 137: The Spacer in CameraControlBar is using the function parameter
modifier (modifier.width(12.dp)), causing callers' modifiers (e.g., padding) to
be inherited; change it to use an independent Modifier for layout-only behavior
by replacing usage of the parameter modifier with a fresh Modifier when creating
the Spacer (i.e., use Modifier.width(12.dp) for the Spacer so it only defines
width and does not inherit caller styles).
- Around line 73-101: The local UI state "enabled" in CameraControlBar is using
rememberSaveable so it persists across capture state changes; replace
rememberSaveable { mutableStateOf(true) } with remember(capture) {
mutableStateOf(true) } (or otherwise derive/reset enabled when capture changes)
so enabled is re-initialized when capture returns to CaptureStatus.NotCaptured;
also set proper contentDescription values for the three Image composables
(ic_gallery -> "갤러리에서 선택", ic_camera_shutter -> "사진 촬영", ic_camera_toggle ->
"카메라 전환") instead of null to improve accessibility; finally change the Spacer at
the noted location so it does not use the parent's modifier and instead uses
Modifier.width(12.dp) only.
In
`@feature/task-certification/src/main/java/com/twix/task_certification/TaskCertificationScreen.kt`:
- Around line 137-143: The onClickUpload handler is a no-op (onClickUpload = {
}) so the Upload button does nothing; replace the empty lambda with the proper
upload action—either dispatch an upload intent (e.g.,
viewModel.dispatch(TaskCertificationIntent.UploadPicture) or a similar
UploadPicture/Submit intent used by your ViewModel) or call the existing upload
method on the ViewModel (e.g., viewModel.uploadPicture()). If upload
functionality isn't implemented yet, disable or hide the Upload button by wiring
it to an isUploadEnabled flag from the ViewModel (or return early) so the UI
doesn't present a non-functional control; reference onClickUpload and
viewModel.dispatch/TaskCertificationIntent to locate where to change.
🧹 Nitpick comments (5)
feature/task-certification/src/main/res/values/strings.xml (1)
3-4: 다국어 리소스 동기화 여부 확인 부탁드립니다.
기본 strings.xml에만 추가되면 다른 로케일(values-xx)이 있을 경우 해당 문자열이 누락되어 fallback만 사용됩니다. 다른 로케일 리소스가 있다면 동일 키를 추가해 동기화하는지 확인해 주세요.As per coding guidelines, [리소스 리뷰 가이드] - 다국어 지원을 고려했는가?
feature/task-certification/src/main/res/drawable/ic_camera_refresh.xml (1)
6-12: 하드코딩 색상은 테마/다크모드 대응에 취약합니다.
현재 strokeColor가#ffffff로 고정되어 있어 테마 변경 시 일관성이 깨질 수 있습니다. 디자인 시스템 컬러(@color/… 또는 테마 속성)로 교체하는 방안을 고려해 주세요.As per coding guidelines, [리소스 리뷰 가이드] - 색상과 테마가 디자인 시스템에 포함되는가?
feature/task-certification/src/main/res/drawable/ic_gallery.xml (1)
6-18: 하드코딩 색상은 테마 일관성에 제약이 있습니다.
배경/스트로크가 고정된 HEX 컬러로 지정되어 있어 테마 변경 시 불일치가 날 수 있습니다. 디자인 시스템 컬러 리소스로 치환 가능한지 검토해 주세요.As per coding guidelines, [리소스 리뷰 가이드] - 색상과 테마가 디자인 시스템에 포함되는가?
core/ui/src/main/java/com/twix/ui/base/ObserveAsEvents.kt (1)
23-35: 이벤트 람다 변경 시 최신 참조가 유지되지 않을 수 있습니다.왜 문제가 되는지:
LaunchedEffect키에event가 포함되어 있지 않아 recomposition에서 람다가 바뀌어도 이전 람다로 계속 수집될 수 있습니다.
어떻게 개선할지:rememberUpdatedState로 최신 람다를 참조하거나event를LaunchedEffect키로 추가하세요.✅ 제안 변경
+import androidx.compose.runtime.rememberUpdatedState ... `@Composable` fun <T> ObserveAsEvents( flow: Flow<T>, event: suspend (T) -> Unit, ) { val lifecycleOwner = LocalLifecycleOwner.current + val currentEvent by rememberUpdatedState(event) LaunchedEffect(flow, lifecycleOwner) { lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { withContext(Dispatchers.Main.immediate) { - flow.collect(event) + flow.collect { currentEvent(it) } } } } }core/design-system/src/main/java/com/twix/designsystem/components/AppRoundButton.kt (1)
65-97: 다크 모드 프리뷰 추가로 색상 대비를 확인해주세요.왜 문제가 되는지: 디자인 시스템 컴포넌트는 다크 모드에서 대비/가독성 이슈가 생길 수 있는데 현재 프리뷰가 라이트 모드만 있어 확인이 어렵습니다.
어떻게 개선할지: 다크 모드 프리뷰를 추가해 색상/대비를 함께 검증하세요.As per coding guidelines: [디자인 시스템 리뷰 가이드] - Dark Mode 지원 여부.✅ 제안 변경
+import android.content.res.Configuration ... -@Preview(showBackground = true) +@Preview(showBackground = true) +@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) `@Composable` fun AppRoundButtonPreview() { TwixTheme { Column {
...e/task-certification/src/main/java/com/twix/task_certification/component/CameraControlBar.kt
Outdated
Show resolved
Hide resolved
...e/task-certification/src/main/java/com/twix/task_certification/component/CameraControlBar.kt
Show resolved
Hide resolved
...e/task-certification/src/main/java/com/twix/task_certification/component/CameraControlBar.kt
Outdated
Show resolved
Hide resolved
feature/task-certification/src/main/java/com/twix/task_certification/TaskCertificationScreen.kt
Show resolved
Hide resolved
|
|
||
| private fun pickPicture(uri: Uri?) { | ||
| uri?.let { updatePickPicture(uri) } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mediaPicker에서 이미지가 null인 경우는 이미지를 선택하지 않은 상태에서 미디어 피커를 닫은 경우라 따로 에러처리 하지 않았어 !
dogmania
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다! 문자열 가져다 쓰는 방식은 Composable 내부에서 최대한 stringResource로 통일하면 좋을 거 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금도 좋긴 한데 내용물이 항상 Text 기반이니까 content를 받지 말고 text, textColor를 추가하는 것도 괜찮을 거 같아요. 그리고 지금 border가 없는 버튼의 경우는 이 컴포저블로 표현이 안되는 거 같아요 borderColor랑 backgroundColor를 같은 색으로 맞춰서 표현한다고 해도 버튼 높이가 다르고 내부 정렬이 안 맞아서 이 부분도 재사용 가능하게 수정 부탁드려요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
border를 선택해서 전달하도록 수정해봤어 !
리뷰 반영 커밋 : 12297dd
| withContext(Dispatchers.Main.immediate) { | ||
| flow.collect(event) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LaunchedEffect 자체가 메인 스레드에서 작동하는 걸로 알고 있어서 withContext는 제거해도 괜찮을 거 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아래 리뷰랑 한번에 반영했어 !
리뷰 반영 커밋 : 2fab411
| @Composable | ||
| fun <T> ObserveAsEvents( | ||
| flow: Flow<T>, | ||
| event: suspend (T) -> Unit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메서드 파라미터니까 네이밍은 onEvent로 바꾸면 어떨까요
| onClickGallery: () -> Unit, | ||
| modifier: Modifier = Modifier, | ||
| ) { | ||
| var enabled by rememberSaveable { mutableStateOf(true) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 플래그 변수는 rememberSaveable로 복원할 필요가 있을까 싶은데 remember를 안 쓰는 이유가 따로 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
상태가 변경되도 유지하려는 의도였는데 생각해보니
촬영하면 바로 버튼 자체의 가시성이 변경되다보니 rememberSaveable를 안써도 되겠군 !
리뷰 반영 커밋 : ca84073
| onCaptureClick() | ||
| enabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
플래그를 먼저 바꾸고 콜백을 호출하는 게 더 안정적일 거 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음 ! 좋은 의견인 것 같아 !!
리뷰 반영 커밋 : a242104
| TaskCertificationSideEffect.ImageCaptureFailException -> { | ||
| toastManager.tryShow( | ||
| ToastData( | ||
| message = context.getString(R.string.task_certification_image_capture_fail), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 이 코드에서 Querying resource values using LocalContext.current 이런 Lint 경고가 뜨고 있어요! string 가져다 쓸 때는 stringResource로 통일해주세요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이슈 번호
#38
리뷰/머지 희망 기한 (선택)
2026.02.02
작업내용
결과물
default.mp4
리뷰어에게 추가로 요구하는 사항 (선택)
피그마에 있는 round 버튼을 재사용할 수 있도록 구현해봤는데 요거 재사용 가능할지 확인 부탁해 !

커밋