22
33package com.shifthackz.aisdv1.presentation.screen.img2img
44
5+ import androidx.activity.compose.rememberLauncherForActivityResult
6+ import androidx.activity.result.PickVisualMediaRequest
7+ import androidx.activity.result.contract.ActivityResultContracts
58import androidx.compose.foundation.background
69import androidx.compose.foundation.clickable
710import androidx.compose.foundation.layout.Arrangement
@@ -53,6 +56,7 @@ import androidx.compose.ui.res.stringResource
5356import androidx.compose.ui.text.input.TextFieldValue
5457import androidx.compose.ui.unit.dp
5558import androidx.compose.ui.unit.sp
59+ import androidx.core.content.FileProvider
5660import com.shifthackz.aisdv1.core.common.file.FileProviderDescriptor
5761import com.shifthackz.aisdv1.core.common.math.roundTo
5862import com.shifthackz.aisdv1.core.model.UiText
@@ -70,33 +74,73 @@ import com.shifthackz.aisdv1.presentation.screen.inpaint.components.InPaintCompo
7074import com.shifthackz.aisdv1.presentation.theme.sliderColors
7175import com.shifthackz.aisdv1.presentation.utils.Constants.DENOISING_STRENGTH_MAX
7276import com.shifthackz.aisdv1.presentation.utils.Constants.DENOISING_STRENGTH_MIN
77+ import com.shifthackz.aisdv1.presentation.utils.PermissionUtil
78+ import com.shifthackz.aisdv1.presentation.utils.uriToBitmap
7379import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputForm
7480import com.shifthackz.aisdv1.presentation.widget.toolbar.GenerationBottomToolbar
7581import com.shifthackz.aisdv1.presentation.widget.work.BackgroundWorkWidget
76- import com.shz.imagepicker.imagepicker.ImagePicker
77- import com.shz.imagepicker.imagepicker.model.GalleryPicker
7882import org.koin.androidx.compose.koinViewModel
7983import org.koin.compose.koinInject
84+ import java.io.File
8085import com.shifthackz.aisdv1.core.localization.R as LocalizationR
8186
8287@Composable
8388fun ImageToImageScreen () {
8489 val context = LocalContext .current
8590 val viewModel = koinViewModel<ImageToImageViewModel >()
8691 val fileProviderDescriptor: FileProviderDescriptor = koinInject()
92+
93+ val cameraFile = File (context.cacheDir, " camera.jpg" ).apply {
94+ createNewFile()
95+ deleteOnExit()
96+ }
97+
98+ val cameraUri = FileProvider .getUriForFile(
99+ context,
100+ fileProviderDescriptor.providerPath,
101+ cameraFile,
102+ )
103+
104+ val cameraPicker = rememberLauncherForActivityResult(
105+ ActivityResultContracts .TakePicture (),
106+ ) { success ->
107+ if (! success) return @rememberLauncherForActivityResult
108+ val bitmap = uriToBitmap(context, cameraUri) ? : return @rememberLauncherForActivityResult
109+ viewModel.processIntent(ImageToImageIntent .CropImage (bitmap))
110+ }
111+
112+ val cameraPermission = rememberLauncherForActivityResult(
113+ ActivityResultContracts .RequestPermission ()
114+ ) { isGranted ->
115+ if (! isGranted) return @rememberLauncherForActivityResult
116+ cameraPicker.launch(cameraUri)
117+ }
118+
119+ val mediaPicker = rememberLauncherForActivityResult(
120+ ActivityResultContracts .PickVisualMedia (),
121+ ) { uri ->
122+ val bitmap =
123+ uri?.let { uriToBitmap(context, it) } ? : return @rememberLauncherForActivityResult
124+ viewModel.processIntent(ImageToImageIntent .CropImage (bitmap))
125+ }
126+
87127 MviComponent (
88128 viewModel = viewModel,
89129 processEffect = { effect ->
90- ImagePicker .Builder (fileProviderDescriptor.providerPath) { result ->
91- viewModel.processIntent(ImageToImageIntent .CropImage (result))
130+ when (effect) {
131+ ImageToImageEffect .GalleryPicker -> {
132+ val request = PickVisualMediaRequest (
133+ ActivityResultContracts .PickVisualMedia .ImageOnly ,
134+ )
135+ mediaPicker.launch(request)
136+ }
137+
138+ ImageToImageEffect .CameraPicker -> {
139+ if (PermissionUtil .checkCameraPermission(context, cameraPermission::launch)) {
140+ cameraPicker.launch(cameraUri)
141+ }
142+ }
92143 }
93- .useGallery(effect == ImageToImageEffect .GalleryPicker )
94- .useCamera(effect == ImageToImageEffect .CameraPicker )
95- .autoRotate(effect == ImageToImageEffect .GalleryPicker )
96- .multipleSelection(false )
97- .galleryPicker(GalleryPicker .NATIVE )
98- .build()
99- .launch(context)
100144 },
101145 ) { state, intentHandler ->
102146 ScreenContent (
@@ -111,7 +155,7 @@ fun ImageToImageScreen() {
111155private fun ScreenContent (
112156 modifier : Modifier = Modifier ,
113157 state : ImageToImageState ,
114- processIntent : (GenerationMviIntent ) -> Unit = {}
158+ processIntent : (GenerationMviIntent ) -> Unit = {},
115159) {
116160 val promptChipTextFieldState = remember { mutableStateOf(TextFieldValue ()) }
117161 val negativePromptChipTextFieldState = remember { mutableStateOf(TextFieldValue ()) }
@@ -340,7 +384,7 @@ private fun ScreenContent(
340384 ServerSource .OPEN_AI -> LocalizationR .string.action_change_configuration
341385
342386 else -> LocalizationR .string.action_generate
343- }
387+ },
344388 ),
345389 color = LocalContentColor .current,
346390 )
@@ -499,7 +543,7 @@ private fun ImagePickButtonBox(
499543 id = when (buttonType) {
500544 ImagePickButton .PHOTO -> LocalizationR .string.action_image_picker_gallery
501545 ImagePickButton .CAMERA -> LocalizationR .string.action_image_picker_camera
502- }
546+ },
503547 ),
504548 fontSize = 17 .sp,
505549 )
0 commit comments