Skip to content

Commit 44399b4

Browse files
Implement 'Take photo' action in the media picker
1 parent 0cc89bc commit 44399b4

File tree

6 files changed

+25
-7
lines changed

6 files changed

+25
-7
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ junit = "4.13.2"
1616
mockk = "1.13.9"
1717
appcompat = "1.7.0"
1818
material = "1.12.0"
19-
ucrop = "2.2.9"
19+
ucrop = "2.2.9-native"
2020
coil = "2.7.0"
2121
activityCompose = "1.9.0"
2222
robolectric = "4.12.2"

gravatar-quickeditor/src/main/java/com/gravatar/quickeditor/data/FileUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import java.io.File
88
internal class FileUtils(
99
private val context: Context,
1010
) {
11-
fun createTempFile(): File {
12-
return File(context.cacheDir, "gravatar_${System.currentTimeMillis()}")
11+
fun createCroppedAvatarFile(): File {
12+
return File(context.cacheDir, "cropped_avatar_${System.currentTimeMillis()}.jpg")
1313
}
1414

1515
fun deleteFile(uri: Uri) {

gravatar-quickeditor/src/main/java/com/gravatar/quickeditor/ui/avatarpicker/AvatarPicker.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.gravatar.quickeditor.ui.avatarpicker
22

33
import android.content.Context
44
import android.content.Intent
5+
import android.graphics.Bitmap
56
import android.graphics.Color
67
import android.net.Uri
78
import androidx.activity.compose.rememberLauncherForActivityResult
@@ -163,7 +164,8 @@ internal fun AvatarPicker(
163164
}
164165
}
165166

166-
private const val UCROP_COMPRESSION_QUALITY = 100
167+
private const val UCROP_COMPRESSION_QUALITY = 90
168+
private const val UCROP_MAX_IMAGE_SIZE = 1080
167169

168170
private fun ActivityResultLauncher<Intent>.launchAvatarCrop(image: Uri, tempFile: File, context: Context) {
169171
val options = UCrop.Options().apply {
@@ -172,6 +174,8 @@ private fun ActivityResultLauncher<Intent>.launchAvatarCrop(image: Uri, tempFile
172174
setToolbarWidgetColor(Color.WHITE)
173175
setAllowedGestures(UCropActivity.SCALE, UCropActivity.ROTATE, UCropActivity.NONE)
174176
setCompressionQuality(UCROP_COMPRESSION_QUALITY)
177+
setCompressionFormat(Bitmap.CompressFormat.JPEG)
178+
withMaxResultSize(UCROP_MAX_IMAGE_SIZE, UCROP_MAX_IMAGE_SIZE)
175179
setCircleDimmedLayer(true)
176180
}
177181
launch(

gravatar-quickeditor/src/main/java/com/gravatar/quickeditor/ui/avatarpicker/AvatarPickerViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ internal class AvatarPickerViewModel(
7171

7272
fun localImageSelected(imageUri: Uri) {
7373
viewModelScope.launch {
74-
_actions.send(AvatarPickerAction.LaunchImageCropper(imageUri, fileUtils.createTempFile()))
74+
_actions.send(AvatarPickerAction.LaunchImageCropper(imageUri, fileUtils.createCroppedAvatarFile()))
7575
}
7676
}
7777

gravatar-quickeditor/src/main/java/com/gravatar/quickeditor/ui/components/AvatarsSection.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ import androidx.compose.runtime.setValue
2929
import androidx.compose.ui.Alignment
3030
import androidx.compose.ui.Modifier
3131
import androidx.compose.ui.layout.onPlaced
32+
import androidx.compose.ui.platform.LocalContext
3233
import androidx.compose.ui.res.stringResource
3334
import androidx.compose.ui.text.font.FontWeight
3435
import androidx.compose.ui.tooling.preview.Preview
3536
import androidx.compose.ui.unit.IntOffset
3637
import androidx.compose.ui.unit.dp
3738
import androidx.compose.ui.unit.sp
39+
import com.gravatar.quickeditor.QuickEditorFileProvider
3840
import com.gravatar.quickeditor.R
3941
import com.gravatar.quickeditor.ui.avatarpicker.AvatarUi
4042
import com.gravatar.quickeditor.ui.avatarpicker.AvatarsSectionUiState
@@ -50,14 +52,21 @@ internal fun AvatarsSection(
5052
onLocalImageSelected: (Uri) -> Unit,
5153
modifier: Modifier = Modifier,
5254
) {
55+
val context = LocalContext.current
5356
var popupVisible by rememberSaveable { mutableStateOf(false) }
5457
var popupYOffset by rememberSaveable { mutableIntStateOf(0) }
58+
var photoImageUri by rememberSaveable { mutableStateOf<Uri?>(null) }
5559
val listState = rememberLazyListState()
5660

5761
val pickMedia = rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
5862
uri?.let { onLocalImageSelected(it) }
5963
}
6064

65+
val takePhoto = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
66+
val takenPictureUri = photoImageUri
67+
if (success && takenPictureUri != null) onLocalImageSelected(takenPictureUri)
68+
}
69+
6170
LaunchedEffect(state.scrollToIndex) {
6271
state.scrollToIndex?.let { listState.scrollToItem(it) }
6372
}
@@ -133,7 +142,12 @@ internal fun AvatarsSection(
133142
popupVisible = false
134143
pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
135144
},
136-
onTakePhotoClick = { popupVisible = false },
145+
onTakePhotoClick = {
146+
popupVisible = false
147+
val imageUri = QuickEditorFileProvider.getTempCameraImageUri(context)
148+
photoImageUri = imageUri
149+
takePhoto.launch(imageUri)
150+
},
137151
)
138152
}
139153
}

gravatar-quickeditor/src/test/java/com/gravatar/quickeditor/ui/avatarpicker/AvatarPickerViewModelTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class AvatarPickerViewModelTest {
267267
fun `given local image when selected then launch cropper action sent`() = runTest {
268268
val file = mockk<File>()
269269
val uri = mockk<Uri>()
270-
every { fileUtils.createTempFile() } returns file
270+
every { fileUtils.createCroppedAvatarFile() } returns file
271271

272272
viewModel = initViewModel()
273273

0 commit comments

Comments
 (0)