@@ -5,59 +5,40 @@ import android.content.res.Configuration
55import android.graphics.Bitmap
66import android.net.Uri
77import androidx.activity.compose.rememberLauncherForActivityResult
8- import androidx.activity.result.PickVisualMediaRequest
98import androidx.activity.result.contract.ActivityResultContracts
10- import androidx.compose.foundation.layout.Arrangement
11- import androidx.compose.foundation.layout.Column
12- import androidx.compose.foundation.layout.Spacer
13- import androidx.compose.foundation.layout.fillMaxSize
14- import androidx.compose.foundation.layout.height
15- import androidx.compose.foundation.layout.padding
16- import androidx.compose.foundation.layout.size
17- import androidx.compose.material3.Button
18- import androidx.compose.material3.Text
9+ import androidx.compose.foundation.background
10+ import androidx.compose.material3.MaterialTheme
1911import androidx.compose.runtime.Composable
2012import androidx.compose.runtime.LaunchedEffect
2113import androidx.compose.runtime.getValue
2214import androidx.compose.runtime.mutableStateOf
2315import androidx.compose.runtime.remember
2416import androidx.compose.runtime.setValue
25- import androidx.compose.ui.Alignment
2617import androidx.compose.ui.Modifier
27- import androidx.compose.ui.draw.alpha
2818import androidx.compose.ui.platform.LocalContext
29- import androidx.compose.ui.res.stringResource
3019import androidx.compose.ui.tooling.preview.Preview
31- import androidx.compose.ui.unit.dp
3220import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
3321import androidx.hilt.navigation.compose.hiltViewModel
3422import androidx.lifecycle.compose.LocalLifecycleOwner
3523import androidx.lifecycle.lifecycleScope
36- import com.abizer_r.quickedit.R
3724import com.abizer_r.quickedit.theme.QuickEditTheme
38- import com.abizer_r.quickedit.ui.common.ErrorView
39- import com.abizer_r.quickedit.ui.common.LoadingView
40- import com.abizer_r.quickedit.ui.common.PermissionDeniedView
4125import com.abizer_r.quickedit.ui.common.permission.PermissionDialog
4226import com.abizer_r.quickedit.ui.common.permission.StoragePermissionTextProvider
43- import com.abizer_r.quickedit.ui.navigation.NavDestinations
4427import com.abizer_r.quickedit.utils.FileUtils
4528import com.abizer_r.quickedit.utils.PermissionUtils
46- import com.abizer_r.quickedit.utils.PermissionUtils.PermissionTypes
4729import com.abizer_r.quickedit.utils.getActivity
4830import com.abizer_r.quickedit.utils.getOpenAppSettingsIntent
4931import com.abizer_r.quickedit.utils.other.bitmap.BitmapStatus
5032import com.abizer_r.quickedit.utils.other.bitmap.BitmapUtils
51- import com.abizer_r.quickedit.utils.toast
5233import kotlinx.coroutines.Dispatchers
53- import kotlinx.coroutines.delay
5434import kotlinx.coroutines.flow.collect
5535import kotlinx.coroutines.flow.onEach
5636import kotlinx.coroutines.launch
5737import java.io.File
5838
5939@Composable
6040fun MainScreen (
41+ modifier : Modifier = Modifier ,
6142 onImageSelected : (Bitmap ) -> Unit
6243) {
6344 val context = LocalContext .current
@@ -78,7 +59,7 @@ fun MainScreen(
7859 isGranted = perms[permission] == true
7960 )
8061 }
81- if (perms.values.all { true }) {
62+ if (perms.values.all { granted -> granted }) {
8263 viewModel.permissionsGranted.value = true
8364 }
8465 }
@@ -101,13 +82,17 @@ fun MainScreen(
10182 FileUtils .getUriForFile(context, imgFile)
10283 }
10384
104- val onPhotoPicked = remember< (Uri ? ) -> Unit > {{
105- imageUri = it
106- }}
85+ val onPhotoPicked = remember< (Uri ? ) -> Unit > {
86+ {
87+ imageUri = it
88+ }
89+ }
10790
108- val onPhotoCaptured = remember< (Uri ? ) -> Unit > {{
109- imageUri = it
110- }}
91+ val onPhotoCaptured = remember< (Uri ? ) -> Unit > {
92+ {
93+ imageUri = it
94+ }
95+ }
11196
11297 LaunchedEffect (key1 = imageUri) {
11398 imageUri?.let { imgUri ->
@@ -119,63 +104,16 @@ fun MainScreen(
119104 }
120105 }
121106
122- val handleImageSelected = remember< (Bitmap ) -> Unit > {{
123- lifecycleScope.launch {
124- // delay(1000)
125- onImageSelected(it)
126- }
127- }}
128-
129- when (val bitmapStatus = scaledBitmapStatus) {
130- BitmapStatus .None -> {
131- if (permissionsGranted) {
132- MainScreenLayout (
133- cameraImageUri,
134- onPhotoPicked,
135- onPhotoCaptured
136- )
137- } else {
138- PermissionDeniedView (
139- modifier = Modifier
140- .fillMaxSize()
141- .padding(48 .dp),
142- permissionTypes = arrayListOf (PermissionTypes .INTERNAL_STORAGE ),
143- launchAppSettings = {
144- appSettingsLauncher.launch(context.getOpenAppSettingsIntent())
145- }
146- )
147- }
148- }
149-
150- BitmapStatus .Processing -> {
151- MainScreenLayout (
152- cameraImageUri,
153- onPhotoPicked,
154- onPhotoCaptured,
155- showLoading = true
156- )
157- // LoadingView(modifier = Modifier.fillMaxSize())
158- }
159-
160- is BitmapStatus .Failed -> {
161- val errorText = bitmapStatus.errorMsg ? : bitmapStatus.exception?.message
162- ? : stringResource(R .string.something_went_wrong)
163- ErrorView (
164- modifier = Modifier .fillMaxSize(),
165- errorText = errorText
166- )
167- }
168-
169- is BitmapStatus .Success -> {
170- handleImageSelected(bitmapStatus.scaledBitmap)
171- // show layout to avoid showing blank screen while transition animation is played
172- MainScreenLayout (
173- cameraImageUri!! ,
174- onPhotoPicked,
175- onPhotoCaptured
176- )
177- }
178- }
107+ MainScreenLayout (
108+ modifier = modifier,
109+ scaledBitmapStatus = scaledBitmapStatus,
110+ permissionsGranted = permissionsGranted,
111+ cameraImageUri = cameraImageUri,
112+ appSettingsLauncher = appSettingsLauncher,
113+ onPhotoPicked = onPhotoPicked,
114+ onPhotoCaptured = onPhotoCaptured,
115+ onImageSelected = onImageSelected
116+ )
179117
180118 dialogQueue.reversed().forEach { permission ->
181119 PermissionDialog (
@@ -184,6 +122,7 @@ fun MainScreen(
184122 Manifest .permission.READ_EXTERNAL_STORAGE -> {
185123 StoragePermissionTextProvider ()
186124 }
125+
187126 else -> return @forEach
188127 },
189128 isPermanentlyDeclined = ! shouldShowRequestPermissionRationale(
@@ -204,82 +143,4 @@ fun MainScreen(
204143 }
205144 )
206145 }
207- }
208-
209- @Composable
210- fun MainScreenLayout (
211- cameraImageUri : Uri ? ,
212- onPhotoPicked : (Uri ? ) -> Unit ,
213- onPhotoCaptured : (Uri ? ) -> Unit ,
214- showLoading : Boolean = false
215- ) {
216- val context = LocalContext .current
217-
218- val photoPickerLauncher = rememberLauncherForActivityResult(
219- contract = ActivityResultContracts .PickVisualMedia (),
220- onResult = onPhotoPicked
221- )
222-
223- val photoCaptureLauncher = rememberLauncherForActivityResult(
224- contract = ActivityResultContracts .TakePicture (),
225- onResult = { isTaken ->
226- if (isTaken) onPhotoCaptured(cameraImageUri)
227- }
228- )
229-
230- /* *
231- *
232- *
233- *
234- * TODO - add some title or logo for "QuickEdit"
235- *
236- *
237- *
238- */
239- Column (
240- modifier = Modifier .fillMaxSize(),
241- verticalArrangement = Arrangement .Center ,
242- horizontalAlignment = Alignment .CenterHorizontally
243- ) {
244- Button (onClick = {
245- photoPickerLauncher.launch(
246- PickVisualMediaRequest (ActivityResultContracts .PickVisualMedia .ImageOnly )
247- )
248- }
249- ) { Text (stringResource(R .string.pick_image)) }
250-
251- Spacer (modifier = Modifier .height(16 .dp))
252-
253- Button (onClick = {
254- if (cameraImageUri != null ) {
255- photoCaptureLauncher.launch(cameraImageUri)
256- } else {
257- context.toast(R .string.something_went_wrong)
258- }
259- }
260- ) { Text (stringResource(R .string.capture_image)) }
261-
262- Spacer (modifier = Modifier .height(16 .dp))
263-
264- LoadingView (
265- modifier = Modifier
266- .size(48 .dp)
267- .alpha(if (showLoading) 1f else 0f ),
268- progressBarSize = 32 .dp,
269- progressBarStrokeWidth = 3 .dp
270- )
271- }
272- }
273-
274-
275- @Preview(uiMode = Configuration .UI_MODE_NIGHT_YES )
276- @Composable
277- fun PreviewMainScreen () {
278- QuickEditTheme {
279- MainScreenLayout (
280- cameraImageUri = Uri .EMPTY ,
281- onPhotoPicked = {},
282- onPhotoCaptured = {}
283- )
284- }
285146}
0 commit comments