customization mprovements

This commit is contained in:
Phillip Thelen 2024-04-15 11:34:29 +02:00
parent b4469d11a3
commit cfbbe092d7
12 changed files with 96 additions and 33 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1489,6 +1489,10 @@
<string name="avatar_beards">Beards</string>
<string name="standard_backgrounds">Standard Backgrounds</string>
<string name="avatar_hair_colors">Hair Colors</string>
<string name="looking_for_more">Looking for more?</string>
<string name="customization_shop_more">Check out the Customization Shop for even more ways to customize your avatar!</string>
<string name="customizations_no_owned">You dont own any of these items</string>
<string name="customization_shop_check_out">Head over to the Customization Shop to browse the many ways you can customize your avatar!</string>
<plurals name="you_x_others">

View file

@ -53,7 +53,8 @@ class UserRepositoryImpl(
override suspend fun syncUserStats(): User? {
val user = apiClient.syncUserStats()
if (user?.stats?.toNextLevel != null) {
if (user != null && (user.stats?.toNextLevel ?: 0) > 1
&& (user.stats?.maxMP ?: 0) > 1) {
localRepository.saveUser(user)
} else {
retrieveUser(false, true)

View file

@ -17,7 +17,10 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
@ -28,6 +31,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
@ -41,6 +45,7 @@ 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.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -55,11 +60,13 @@ import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.databinding.BottomSheetBackgroundsFilterBinding
import com.habitrpg.android.habitica.databinding.FragmentComposeBinding
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.CustomizationFilter
import com.habitrpg.android.habitica.models.inventory.Customization
import com.habitrpg.android.habitica.models.user.OwnedCustomization
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
import com.habitrpg.android.habitica.ui.theme.colors
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.PixelArtView
@ -67,8 +74,11 @@ import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.common.habitica.extensions.setTintWith
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.MainNavigationController
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.common.habitica.theme.HabiticaTheme
import com.habitrpg.common.habitica.views.ComposableAvatarView
import com.habitrpg.shared.habitica.models.Avatar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
@ -124,6 +134,9 @@ class AvatarCustomizationFragment :
return FragmentComposeBinding.inflate(inflater, container, false)
}
@Inject
lateinit var configManager: AppConfigManager
@Inject
lateinit var customizationRepository: CustomizationRepository
@ -146,6 +159,7 @@ class AvatarCustomizationFragment :
savedInstanceState: Bundle?
): View? {
showsBackButton = true
hidesToolbar = true
val view = super.onCreateView(inflater, container, savedInstanceState)
binding?.composeView?.apply {
@ -155,7 +169,8 @@ class AvatarCustomizationFragment :
val userSize by viewModel.userSize
val hairColor by viewModel.hairColor
val activeCustomization by viewModel.activeCustomization
AvatarCustomizationView(viewModel.customizations, userSize, hairColor, stringResource(viewModel.typeNameId), activeCustomization) { customization ->
val avatar by userViewModel.user.observeAsState()
AvatarCustomizationView(avatar = avatar, configManager = configManager, viewModel.customizations, userSize, hairColor, type, stringResource(viewModel.typeNameId), activeCustomization) { customization ->
lifecycleScope.launchCatching {
if (customization.identifier?.isNotBlank() != true) {
userRepository.useCustomization(type ?: "", category, activeCustomization ?: "")
@ -217,6 +232,12 @@ class AvatarCustomizationFragment :
} else {
filterMenuItem?.isVisible = false
}
mainActivity?.toolbar?.let {
val color = ContextCompat.getColor(requireContext(), R.color.window_background)
ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color)
requireActivity().window.statusBarColor = color
}
}
private fun updateFilterIcon() {
@ -397,43 +418,80 @@ class AvatarCustomizationFragment :
}
@Composable
private fun AvatarCustomizationView(customizations: List<Customization>, userSize: String, hairColor: String?, typeName: String, activeCustomization: String?, onSelect: (Customization) -> Unit) {
private fun AvatarCustomizationView(avatar: Avatar?, configManager: AppConfigManager, customizations: List<Customization>, userSize: String, hairColor: String?, type: String?, typeName: String, activeCustomization: String?, onSelect: (Customization) -> Unit) {
val nestedScrollInterop = rememberNestedScrollInteropConnection()
val totalWidth = LocalConfiguration.current.screenWidthDp.dp
val horizontalPadding = (totalWidth - (84.dp * 3)) / 2
LazyVerticalGrid(
columns = GridCells.Adaptive(76.dp),
horizontalArrangement = Arrangement.Center,
contentPadding = PaddingValues(horizontal = horizontalPadding),
modifier = Modifier.nestedScroll(nestedScrollInterop)
) {
item(span = { GridItemSpan(3) }) {
Text(
typeName.uppercase(),
fontSize = 12.sp,
color = colorResource(id = R.color.text_ternary),
textAlign = TextAlign.Center,
modifier = Modifier.padding(10.dp)
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.background(colorResource(R.color.window_background))) {
ComposableAvatarView(
avatar = avatar, configManager = configManager, modifier = Modifier
.padding(vertical = 24.dp)
.size(140.dp, 147.dp)
)
Box(
Modifier
.background(colorResource(R.color.content_background), RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
.fillMaxWidth()
.height(22.dp)
)
}
items(customizations) { customization ->
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(4.dp)
.border(if (activeCustomization == customization.identifier) 2.dp else 0.dp, if (activeCustomization == customization.identifier) HabiticaTheme.colors.tintedUiMain else colorResource(R.color.transparent), RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
.clickable {
onSelect(customization)
LazyVerticalGrid(
columns = GridCells.Adaptive(76.dp),
horizontalArrangement = Arrangement.Center,
contentPadding = PaddingValues(horizontal = horizontalPadding),
modifier = Modifier
.nestedScroll(nestedScrollInterop)
.background(colorResource(R.color.content_background))
) {
item(span = { GridItemSpan(3) }) {
Text(
typeName.uppercase(),
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = colorResource(id = R.color.text_ternary),
textAlign = TextAlign.Center,
modifier = Modifier.padding(10.dp)
)
}
if (customizations.size > 1) {
items(customizations) { customization ->
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(4.dp)
.border(if (activeCustomization == customization.identifier) 2.dp else 0.dp, if (activeCustomization == customization.identifier) HabiticaTheme.colors.tintedUiMain else colorResource(R.color.transparent), RoundedCornerShape(8.dp))
.clip(RoundedCornerShape(8.dp))
.clickable {
onSelect(customization)
}
.background(colorResource(id = R.color.window_background))) {
if (customization.identifier.isNullOrBlank() || customization.identifier == "0") {
Image(painterResource(R.drawable.empty_slot), contentDescription = null, contentScale = ContentScale.None, modifier = Modifier.size(68.dp))
} else {
PixelArtView(
imageName = customization.getImageName(userSize, hairColor),
Modifier.size(68.dp)
)
}
}
.background(colorResource(id = R.color.window_background))) {
if (customization.identifier.isNullOrBlank() || customization.identifier == "0") {
Image(painterResource(R.drawable.empty_slot), contentDescription = null, contentScale = ContentScale.None, modifier = Modifier.size(68.dp))
} else {
PixelArtView(
imageName = customization.getImageName(userSize, hairColor),
Modifier.size(68.dp)
}
}
item(span = { GridItemSpan(3) }) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(top = 40.dp).clickable {
MainNavigationController.navigate(R.id.customizationsShopFragment)
}) {
Image(
painterResource(if (type == "backgrounds") R.drawable.customization_background else R.drawable.customization_mix),
null, modifier = Modifier.padding(bottom = 12.dp)
)
if (customizations.size <= 1) {
Text(stringResource(R.string.customizations_no_owned), fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colorResource(R.color.text_secondary))
Text(stringResource(R.string.customization_shop_check_out), fontSize = 13.sp, color = colorResource(R.color.text_ternary), textAlign = TextAlign.Center)
} else {
Text(stringResource(R.string.looking_for_more), fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = colorResource(R.color.text_secondary))
Text(stringResource(R.string.customization_shop_more), fontSize = 13.sp, color = colorResource(R.color.text_ternary), textAlign = TextAlign.Center)
}
}
}
}

View file

@ -1,2 +1,2 @@
NAME=4.3.6
CODE=7101
CODE=7181