Skip to content

Commit 12db8ac

Browse files
integrate cropper in MediaPickerDialog
1 parent 2b81a93 commit 12db8ac

3 files changed

Lines changed: 58 additions & 52 deletions

File tree

app/src/main/java/com/streamliners/feature/pickers_sample/comp/MediaPickerSample.kt

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package com.streamliners.feature.pickers_sample.comp
22

3-
import android.content.Context
4-
import android.graphics.Bitmap
5-
import android.net.Uri
63
import androidx.compose.foundation.layout.Arrangement
74
import androidx.compose.foundation.layout.Column
85
import androidx.compose.foundation.layout.fillMaxWidth
@@ -18,18 +15,10 @@ import androidx.compose.runtime.mutableStateOf
1815
import androidx.compose.runtime.remember
1916
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
2017
import androidx.compose.ui.Modifier
21-
import androidx.compose.ui.graphics.ImageBitmap
22-
import androidx.compose.ui.graphics.asAndroidBitmap
2318
import androidx.compose.ui.platform.LocalContext
2419
import androidx.compose.ui.unit.dp
25-
import androidx.core.net.toUri
2620
import com.mr0xf00.easycrop.AspectRatio
27-
import com.mr0xf00.easycrop.CropError
28-
import com.mr0xf00.easycrop.CropResult
29-
import com.mr0xf00.easycrop.CropperStyle
30-
import com.mr0xf00.easycrop.crop
3121
import com.mr0xf00.easycrop.rememberImageCropper
32-
import com.mr0xf00.easycrop.ui.ImageCropperDialog
3322
import com.streamliners.compose.comp.select.LabelledCheckBox
3423
import com.streamliners.compose.comp.select.RadioGroup
3524
import com.streamliners.pickers.media.FromGalleryType
@@ -40,9 +29,6 @@ import com.streamliners.pickers.media.MediaType
4029
import com.streamliners.pickers.media.PickedMedia
4130
import com.streamliners.pickers.media.comp.PickedMediaPreviewList
4231
import com.streamliners.pickers.media.rememberMediaPickerDialogState
43-
import com.streamliners.pickers.media.util.createFile
44-
import com.streamliners.pickers.media.util.getUri
45-
import java.io.FileOutputStream
4632

4733
@Composable
4834
fun MediaPickerSample(
@@ -75,6 +61,8 @@ fun MediaPickerSample(
7561

7662
val allowMultiple = remember { mutableStateOf(false) }
7763

64+
val cropEnable = remember { mutableStateOf(false) }
65+
7866
RadioGroup(
7967
state = type,
8068
options = MediaType.entries.toList(),
@@ -93,6 +81,8 @@ fun MediaPickerSample(
9381

9482
LabelledCheckBox(state = allowMultiple, label = "Allow multiple")
9583

84+
LabelledCheckBox(state = cropEnable, label = "Enable Crop")
85+
9686
val pickedMediaList = remember {
9787
mutableStateListOf<PickedMedia>()
9888
}
@@ -103,15 +93,17 @@ fun MediaPickerSample(
10393
modifier = Modifier.align(CenterHorizontally),
10494
enabled = type.value != null && fromGalleryType.value != null,
10595
onClick = {
106-
mediaPickerDialogState.value = MediaPickerDialogState.Visible(
96+
mediaPickerDialogState.value = MediaPickerDialogState.ShowMediaPicker(
10797
type = type.value!!,
10898
allowMultiple = allowMultiple.value,
10999
fromGalleryType = fromGalleryType.value!!,
110-
cropParams = MediaPickerCropParams.Enabled(
111-
showAspectRatioSelectionButton = false,
112-
showShapeCropButton = false,
113-
lockAspectRatio = AspectRatio(1, 1)
114-
),
100+
cropParams = if (cropEnable.value) {
101+
MediaPickerCropParams.Enabled(
102+
showAspectRatioSelectionButton = false,
103+
showShapeCropButton = false,
104+
lockAspectRatio = AspectRatio(1, 1)
105+
)
106+
} else MediaPickerCropParams.Disabled,
115107
callback = { getResult ->
116108
executeHandlingError {
117109
pickedMediaList.addAll(getResult())

pickers/src/main/java/com/streamliners/pickers/media/MediaPickerDialog.kt

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ import android.app.Activity
55
import android.content.Context
66
import android.content.Intent
77
import android.content.pm.PackageManager
8-
import android.graphics.Bitmap
9-
import android.graphics.BitmapFactory
10-
import android.net.Uri
118
import android.provider.MediaStore
129
import androidx.activity.compose.rememberLauncherForActivityResult
1310
import androidx.activity.result.PickVisualMediaRequest
@@ -32,8 +29,6 @@ import androidx.compose.runtime.mutableStateOf
3229
import androidx.compose.runtime.remember
3330
import androidx.compose.runtime.rememberCoroutineScope
3431
import androidx.compose.ui.Modifier
35-
import androidx.compose.ui.graphics.ImageBitmap
36-
import androidx.compose.ui.graphics.asImageBitmap
3732
import androidx.compose.ui.platform.LocalContext
3833
import androidx.compose.ui.unit.dp
3934
import androidx.compose.ui.window.DialogProperties
@@ -57,32 +52,34 @@ import com.streamliners.pickers.media.util.saveBitmapToFile
5752
import com.streamliners.utils.safeLet
5853
import kotlinx.coroutines.CoroutineScope
5954
import kotlinx.coroutines.launch
60-
import java.io.File
6155

6256

6357
@Composable
6458
fun MediaPickerDialog(
6559
state: MutableState<MediaPickerDialogState>,
6660
authority: String
6761
) {
68-
val data = state.value as? MediaPickerDialogState.Visible
6962
val imageCropper = rememberImageCropper()
63+
val scope = rememberCoroutineScope()
64+
65+
(state.value as? MediaPickerDialogState.ShowImageCropper)?.let { data ->
7066

71-
imageCropper.cropState?.let {
72-
73-
ImageCropperDialog(
74-
state = it,
75-
style = CropperStyle(
76-
autoZoom = false,
77-
guidelines = null
78-
),
79-
showAspectRatioSelectionButton = (data?.cropParams as? MediaPickerCropParams.Enabled)?.showAspectRatioSelectionButton ?: true,
80-
showShapeCropButton = (data?.cropParams as? MediaPickerCropParams.Enabled)?.showAspectRatioSelectionButton ?: true,
81-
lockAspectRatio = (data?.cropParams as? MediaPickerCropParams.Enabled)?.lockAspectRatio
82-
)
67+
imageCropper.cropState?.let {
68+
69+
ImageCropperDialog(
70+
state = it,
71+
style = CropperStyle(
72+
autoZoom = false,
73+
guidelines = null
74+
),
75+
showAspectRatioSelectionButton = (data.cropParams as? MediaPickerCropParams.Enabled)?.showAspectRatioSelectionButton ?: true,
76+
showShapeCropButton = (data.cropParams as? MediaPickerCropParams.Enabled)?.showAspectRatioSelectionButton ?: true,
77+
lockAspectRatio = (data.cropParams as? MediaPickerCropParams.Enabled)?.lockAspectRatio
78+
)
79+
}
8380
}
8481

85-
if (data == null) return
82+
val data = state.value as? MediaPickerDialogState.ShowMediaPicker ?: return
8683

8784
LaunchedEffect(key1 = Unit) {
8885
if (data.cropParams is MediaPickerCropParams.Enabled) {
@@ -128,7 +125,7 @@ fun MediaPickerDialog(
128125

129126
FromGalleryButton(
130127
modifier = Modifier.weight(1f),
131-
state, data, imageCropper, authority
128+
state, data, imageCropper, authority, scope
132129
)
133130
}
134131

@@ -149,7 +146,7 @@ fun MediaPickerDialog(
149146
fun FromCameraButton(
150147
modifier: Modifier,
151148
state: MutableState<MediaPickerDialogState>,
152-
data: MediaPickerDialogState.Visible,
149+
data: MediaPickerDialogState.ShowMediaPicker,
153150
authority: String,
154151
cameraPermissionIsGranted: () -> Boolean,
155152
imageCropper: ImageCropper
@@ -169,6 +166,7 @@ fun FromCameraButton(
169166
when (data.type) {
170167
Image -> {
171168
showImageCropperIfRequired(
169+
state,
172170
data,
173171
PickedMedia.Image(uri, path),
174172
imageCropper,
@@ -185,10 +183,11 @@ fun FromCameraButton(
185183
processVideo(context, uri, path)
186184
)
187185
}
186+
state.dismiss()
188187
}
189188
}
190189
}
191-
state.dismiss()
190+
192191
}
193192
}
194193
)
@@ -247,14 +246,13 @@ fun FromCameraButton(
247246
fun FromGalleryButton(
248247
modifier: Modifier,
249248
state: MutableState<MediaPickerDialogState>,
250-
data: MediaPickerDialogState.Visible,
249+
data: MediaPickerDialogState.ShowMediaPicker,
251250
imageCropper: ImageCropper,
252-
authority: String
251+
authority: String,
252+
scope: CoroutineScope
253253
) {
254254
val context = LocalContext.current
255255

256-
val scope = rememberCoroutineScope()
257-
258256
val documentPickerLauncher = rememberLauncherForActivityResult(
259257
contract = ActivityResultContracts.StartActivityForResult(),
260258
onResult = { result ->
@@ -280,8 +278,10 @@ fun FromGalleryButton(
280278
PickedMedia.Image(uri.toString())
281279
}
282280
}
281+
state.dismiss()
283282
} else {
284283
showImageCropperIfRequired(
284+
state,
285285
data,
286286
PickedMedia.Image(items.first().toString()),
287287
imageCropper,
@@ -299,10 +299,9 @@ fun FromGalleryButton(
299299
processVideo(context, uri.toString())
300300
}
301301
}
302+
state.dismiss()
302303
}
303304
}
304-
305-
state.dismiss()
306305
}
307306
}
308307
)
@@ -319,6 +318,7 @@ fun FromGalleryButton(
319318
when (data.type) {
320319
Image -> {
321320
showImageCropperIfRequired(
321+
state,
322322
data,
323323
PickedMedia.Image(uri.toString()),
324324
imageCropper,
@@ -335,10 +335,10 @@ fun FromGalleryButton(
335335
processVideo(context, uri.toString())
336336
)
337337
}
338+
state.dismiss()
338339
}
339340
}
340341
}
341-
state.dismiss()
342342
}
343343
)
344344

@@ -408,7 +408,8 @@ suspend fun processVideo(
408408
}
409409

410410
fun showImageCropperIfRequired(
411-
data: MediaPickerDialogState.Visible,
411+
state: MutableState<MediaPickerDialogState>,
412+
data: MediaPickerDialogState.ShowMediaPicker,
412413
image: PickedMedia.Image,
413414
imageCropper: ImageCropper,
414415
context: Context,
@@ -418,9 +419,12 @@ fun showImageCropperIfRequired(
418419
) {
419420
data.cropParams as? MediaPickerCropParams.Enabled ?: run {
420421
onReady(image)
422+
state.dismiss()
421423
return
422424
}
423425

426+
state.showImageCropper(data.cropParams)
427+
424428
scope.launch {
425429

426430
// val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, Uri.parse(image.uri))

pickers/src/main/java/com/streamliners/pickers/media/MediaPickerState.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ sealed class MediaPickerDialogState {
1010

1111
data object Hidden: MediaPickerDialogState()
1212

13-
class Visible(
13+
class ShowMediaPicker(
1414
val type: MediaType,
1515
val allowMultiple: Boolean,
1616
val fromGalleryType: FromGalleryType,
@@ -22,6 +22,10 @@ sealed class MediaPickerDialogState {
2222
return "Attach ${type.name}${if (allowMultiple) "s" else ""}"
2323
}
2424
}
25+
26+
class ShowImageCropper(
27+
val cropParams: MediaPickerCropParams = MediaPickerCropParams.Disabled
28+
): MediaPickerDialogState()
2529
}
2630

2731
sealed class PickedMedia(
@@ -91,4 +95,10 @@ fun rememberMediaPickerDialogState(): MutableState<MediaPickerDialogState> {
9195

9296
fun MutableState<MediaPickerDialogState>.dismiss() {
9397
value = MediaPickerDialogState.Hidden
98+
}
99+
100+
fun MutableState<MediaPickerDialogState>.showImageCropper(
101+
params: MediaPickerCropParams
102+
) {
103+
value = MediaPickerDialogState.ShowImageCropper(params)
94104
}

0 commit comments

Comments
 (0)