@@ -11,10 +11,6 @@ import androidx.compose.foundation.layout.height
1111import androidx.compose.foundation.layout.padding
1212import androidx.compose.foundation.layout.size
1313import androidx.compose.foundation.layout.wrapContentSize
14- import androidx.compose.foundation.lazy.LazyRow
15- import androidx.compose.foundation.lazy.items
16- import androidx.compose.foundation.shape.RoundedCornerShape
17- import androidx.compose.material3.Button
1814import androidx.compose.material3.CircularProgressIndicator
1915import androidx.compose.material3.MaterialTheme
2016import androidx.compose.material3.Snackbar
@@ -27,23 +23,13 @@ import androidx.compose.runtime.Composable
2723import androidx.compose.runtime.LaunchedEffect
2824import androidx.compose.runtime.collectAsState
2925import androidx.compose.runtime.getValue
30- import androidx.compose.runtime.mutableIntStateOf
31- import androidx.compose.runtime.mutableStateOf
3226import androidx.compose.runtime.remember
33- import androidx.compose.runtime.saveable.rememberSaveable
34- import androidx.compose.runtime.setValue
3527import androidx.compose.ui.Alignment
3628import androidx.compose.ui.Modifier
37- import androidx.compose.ui.layout.onPlaced
3829import androidx.compose.ui.platform.LocalContext
39- import androidx.compose.ui.res.stringResource
40- import androidx.compose.ui.text.font.FontWeight
4130import androidx.compose.ui.text.style.TextAlign
42- import androidx.compose.ui.tooling.preview.Preview
4331import androidx.compose.ui.tooling.preview.PreviewLightDark
44- import androidx.compose.ui.unit.IntOffset
4532import androidx.compose.ui.unit.dp
46- import androidx.compose.ui.unit.sp
4733import androidx.core.net.toUri
4834import androidx.lifecycle.Lifecycle
4935import androidx.lifecycle.compose.LocalLifecycleOwner
@@ -52,10 +38,9 @@ import androidx.lifecycle.viewmodel.compose.viewModel
5238import com.gravatar.extensions.defaultProfile
5339import com.gravatar.quickeditor.R
5440import com.gravatar.quickeditor.data.repository.IdentityAvatars
41+ import com.gravatar.quickeditor.ui.components.AvatarsSection
5542import com.gravatar.quickeditor.ui.components.EmailLabel
56- import com.gravatar.quickeditor.ui.components.MediaPickerPopup
5743import com.gravatar.quickeditor.ui.components.ProfileCard
58- import com.gravatar.quickeditor.ui.components.SelectableAvatar
5944import com.gravatar.quickeditor.ui.editor.AvatarUpdateResult
6045import com.gravatar.quickeditor.ui.editor.bottomsheet.DEFAULT_PAGE_HEIGHT
6146import com.gravatar.restapi.models.Avatar
@@ -154,75 +139,23 @@ internal fun AvatarPicker(uiState: AvatarPickerUiState, onAvatarSelected: (Avata
154139 }
155140}
156141
157- @Composable
158- private fun AvatarsSection (
159- avatars : List <AvatarUi >,
160- onAvatarSelected : (Avatar ) -> Unit ,
161- modifier : Modifier = Modifier ,
162- ) {
163- var popupVisible by rememberSaveable { mutableStateOf(false ) }
164- var popupYOffset by rememberSaveable { mutableIntStateOf(0 ) }
165- Box (
166- modifier = modifier
167- .border(
168- width = 1 .dp,
169- color = MaterialTheme .colorScheme.surfaceContainerHighest,
170- shape = RoundedCornerShape (8 .dp),
171- )
172- .padding(16 .dp),
173- ) {
174- Column {
175- Text (
176- text = stringResource(id = R .string.avatar_picker_title),
177- fontSize = 22 .sp,
178- fontWeight = FontWeight .Bold ,
179- )
180- Text (
181- text = stringResource(R .string.avatar_picker_description),
182- fontSize = 15 .sp,
183- color = MaterialTheme .colorScheme.tertiary,
184- modifier = Modifier .padding(top = 4 .dp),
185- )
142+ private const val UCROP_COMPRESSION_QUALITY = 100
186143
187- LazyRow (horizontalArrangement = Arrangement .spacedBy(8 .dp), modifier = Modifier .padding(vertical = 24 .dp)) {
188- items(items = avatars, key = { it.avatarId }) { avatarModel ->
189- when (avatarModel) {
190- is AvatarUi .Uploaded -> SelectableAvatar (
191- imageUrl = avatarModel.avatar.fullUrl,
192- isSelected = avatarModel.isSelected,
193- isLoading = avatarModel.isLoading,
194- onAvatarClicked = {
195- onAvatarSelected(avatarModel.avatar)
196- },
197- modifier = Modifier .size(96 .dp),
198- )
199- }
200- }
201- }
202- Button (
203- modifier = Modifier
204- .fillMaxWidth()
205- .onPlaced { layoutCoordinates -> popupYOffset = layoutCoordinates.size.height },
206- onClick = { popupVisible = true },
207- shape = RoundedCornerShape (4 .dp),
208- contentPadding = PaddingValues (14 .dp),
209- ) {
210- Text (
211- text = stringResource(R .string.avatar_picker_upload_image),
212- style = MaterialTheme .typography.titleMedium,
213- )
214- }
215- }
216- if (popupVisible) {
217- MediaPickerPopup (
218- alignment = Alignment .BottomCenter ,
219- onDismissRequest = { popupVisible = false },
220- offset = IntOffset (0 , - popupYOffset - 30 ),
221- onChoosePhotoClick = { popupVisible = false },
222- onTakePhotoClick = { popupVisible = false },
223- )
224- }
144+ private fun ActivityResultLauncher<Intent>.launchAvatarCrop (image : Uri , tempFile : File , context : Context ) {
145+ val options = UCrop .Options ().apply {
146+ setToolbarColor(Color .BLACK )
147+ setStatusBarColor(Color .BLACK )
148+ setToolbarWidgetColor(Color .WHITE )
149+ setAllowedGestures(UCropActivity .SCALE , UCropActivity .ROTATE , UCropActivity .NONE )
150+ setCompressionQuality(UCROP_COMPRESSION_QUALITY )
151+ setCircleDimmedLayer(true )
225152 }
153+ launch(
154+ UCrop .of(image, Uri .fromFile(tempFile))
155+ .withAspectRatio(1f , 1f )
156+ .withOptions(options)
157+ .getIntent(context),
158+ )
226159}
227160
228161@Composable
@@ -271,31 +204,7 @@ private fun AvatarPickerLoadingPreview() {
271204 identityAvatars = null ,
272205 ),
273206 onAvatarSelected = { },
274- )
275- }
276- }
277-
278- @Composable
279- @Preview(showBackground = true )
280- private fun AvatarSectionPreview () {
281- GravatarTheme {
282- AvatarsSection (
283- onAvatarSelected = { },
284- avatars = listOf (
285- AvatarUi .Uploaded (
286- avatar = Avatar {
287- imageUrl = " /image/url"
288- format = 0
289- imageId = " 1"
290- rating = " G"
291- altText = " alt"
292- isCropped = true
293- updatedDate = Instant .now()
294- },
295- isSelected = true ,
296- isLoading = false ,
297- ),
298- ),
207+ onLocalImageSelected = { },
299208 )
300209 }
301210}
0 commit comments