mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3067 Profile | Fix | Profile image menu (#2026)
Co-authored-by: Evgenii Kozlov <enklave.mare.balticum@protonmail.com> Co-authored-by: Evgenii Kozlov <ubuphobos@gmail.com>
This commit is contained in:
parent
7f627dacf2
commit
fa17cd15b3
8 changed files with 136 additions and 27 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.ui_settings.account
|
||||
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
|
@ -7,7 +8,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
@ -20,6 +20,8 @@ import androidx.compose.foundation.text.BasicTextField
|
|||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
|
@ -35,10 +37,10 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
|
@ -46,10 +48,10 @@ import androidx.compose.ui.text.input.ImeAction
|
|||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.foundation.Arrow
|
||||
import com.anytypeio.anytype.core_ui.foundation.Divider
|
||||
import com.anytypeio.anytype.core_ui.foundation.Dragger
|
||||
import com.anytypeio.anytype.core_ui.foundation.Option
|
||||
|
@ -81,7 +83,8 @@ fun ProfileSettingsScreen(
|
|||
onSpacesClicked: () -> Unit,
|
||||
onMembershipClicked: () -> Unit,
|
||||
membershipStatus: MembershipStatus?,
|
||||
showMembership: ShowMembership?
|
||||
showMembership: ShowMembership?,
|
||||
clearProfileImage: () -> Unit
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
|
@ -93,7 +96,8 @@ fun ProfileSettingsScreen(
|
|||
Header(
|
||||
account = account,
|
||||
onNameSet = onNameChange,
|
||||
onProfileIconClick = onProfileIconClick
|
||||
onProfileIconClick = onProfileIconClick,
|
||||
clearProfileImage = clearProfileImage
|
||||
)
|
||||
}
|
||||
item {
|
||||
|
@ -272,7 +276,8 @@ private fun Header(
|
|||
modifier: Modifier = Modifier,
|
||||
account: AccountProfile,
|
||||
onProfileIconClick: () -> Unit,
|
||||
onNameSet: (String) -> Unit
|
||||
onNameSet: (String) -> Unit,
|
||||
clearProfileImage: () -> Unit
|
||||
) {
|
||||
when (account) {
|
||||
is AccountProfile.Data -> {
|
||||
|
@ -286,7 +291,8 @@ private fun Header(
|
|||
ProfileImageBlock(
|
||||
name = account.name,
|
||||
icon = account.icon,
|
||||
onProfileIconClick = onProfileIconClick
|
||||
onProfileIconClick = onProfileIconClick,
|
||||
clearProfileImage = clearProfileImage
|
||||
)
|
||||
}
|
||||
ProfileNameBlock(name = account.name, onNameSet = onNameSet)
|
||||
|
@ -396,8 +402,15 @@ fun ProfileTitleBlock() {
|
|||
fun ProfileImageBlock(
|
||||
name: String,
|
||||
icon: ProfileIconView,
|
||||
onProfileIconClick: () -> Unit
|
||||
onProfileIconClick: () -> Unit,
|
||||
clearProfileImage: () -> Unit
|
||||
) {
|
||||
val isIconMenuExpanded = remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
when (icon) {
|
||||
is ProfileIconView.Image -> {
|
||||
Image(
|
||||
|
@ -408,7 +421,7 @@ fun ProfileImageBlock(
|
|||
.size(96.dp)
|
||||
.clip(RoundedCornerShape(48.dp))
|
||||
.noRippleClickable {
|
||||
onProfileIconClick.invoke()
|
||||
isIconMenuExpanded.value = !isIconMenuExpanded.value
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -438,6 +451,48 @@ fun ProfileImageBlock(
|
|||
}
|
||||
}
|
||||
}
|
||||
MaterialTheme(
|
||||
shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(16.dp))
|
||||
) {
|
||||
DropdownMenu(
|
||||
expanded = isIconMenuExpanded.value,
|
||||
offset = DpOffset(x = 0.dp, y = 6.dp),
|
||||
onDismissRequest = {
|
||||
isIconMenuExpanded.value = false
|
||||
}
|
||||
) {
|
||||
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(context)) {
|
||||
androidx.compose.material.Divider(
|
||||
thickness = 0.5.dp,
|
||||
color = colorResource(id = R.color.shape_primary)
|
||||
)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onProfileIconClick.invoke()
|
||||
isIconMenuExpanded.value = false
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.profile_settings_apply_upload_image),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
isIconMenuExpanded.value = false
|
||||
clearProfileImage.invoke()
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.profile_settings_remove_image),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
|
@ -459,7 +514,8 @@ private fun ProfileSettingPreview() {
|
|||
onSpacesClicked = {},
|
||||
onMembershipClicked = {},
|
||||
membershipStatus = null,
|
||||
showMembership = ShowMembership(true)
|
||||
showMembership = ShowMembership(true),
|
||||
clearProfileImage = {}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,29 +7,23 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary
|
||||
import com.anytypeio.anytype.analytics.base.sendEvent
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.NetworkMode
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.membership.MembershipStatus
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.account.DeleteAccount
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.icon.RemoveObjectIcon
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.icon.SetImageIcon
|
||||
import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.networkmode.GetNetworkMode
|
||||
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
|
||||
import com.anytypeio.anytype.domain.search.PROFILE_SUBSCRIPTION_ID
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.extension.sendScreenSettingsDeleteEvent
|
||||
import com.anytypeio.anytype.core_models.membership.MembershipStatus
|
||||
import com.anytypeio.anytype.domain.search.ProfileSubscriptionManager
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.membership.provider.MembershipProvider
|
||||
import com.anytypeio.anytype.presentation.profile.AccountProfile
|
||||
import com.anytypeio.anytype.presentation.profile.ProfileIconView
|
||||
import com.anytypeio.anytype.presentation.profile.profileIcon
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -48,7 +42,8 @@ class ProfileSettingsViewModel(
|
|||
private val setImageIcon: SetDocumentImageIcon,
|
||||
private val membershipProvider: MembershipProvider,
|
||||
private val getNetworkMode: GetNetworkMode,
|
||||
private val profileContainer: ProfileSubscriptionManager
|
||||
private val profileContainer: ProfileSubscriptionManager,
|
||||
private val removeObjectIcon: RemoveObjectIcon
|
||||
) : BaseViewModel() {
|
||||
|
||||
private val jobs = mutableListOf<Job>()
|
||||
|
@ -150,6 +145,27 @@ class ProfileSettingsViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onClearProfileImage() {
|
||||
viewModelScope.launch {
|
||||
val config = configStorage.getOrNull()
|
||||
if (config != null) {
|
||||
val params = RemoveObjectIcon.Params(objectId = config.profile)
|
||||
removeObjectIcon.async(
|
||||
params = params
|
||||
).fold(
|
||||
onFailure = {
|
||||
Timber.e("Error while removing profile image")
|
||||
},
|
||||
onSuccess = {
|
||||
// do nothing
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Timber.e("Missing config while trying to unset profile image")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val analytics: Analytics,
|
||||
private val container: StorelessSubscriptionContainer,
|
||||
|
@ -159,7 +175,8 @@ class ProfileSettingsViewModel(
|
|||
private val setDocumentImageIcon: SetDocumentImageIcon,
|
||||
private val membershipProvider: MembershipProvider,
|
||||
private val getNetworkMode: GetNetworkMode,
|
||||
private val profileSubscriptionManager: ProfileSubscriptionManager
|
||||
private val profileSubscriptionManager: ProfileSubscriptionManager,
|
||||
private val removeObjectIcon: RemoveObjectIcon
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
|
@ -172,7 +189,8 @@ class ProfileSettingsViewModel(
|
|||
setImageIcon = setDocumentImageIcon,
|
||||
membershipProvider = membershipProvider,
|
||||
getNetworkMode = getNetworkMode,
|
||||
profileContainer = profileSubscriptionManager
|
||||
profileContainer = profileSubscriptionManager,
|
||||
removeObjectIcon = removeObjectIcon
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue