From 06c94a4f210d87343820c9bd32cd96df31a3d998 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Mar 2023 11:24:02 +0100 Subject: [PATCH] fix party seeking UX --- .../android/habitica/models/members/Member.kt | 2 +- .../social/party/PartySeekingFragment.kt | 78 +++++-------------- .../android/habitica/ui/views/ClassText.kt | 50 ++++++++++++ version.properties | 2 +- 4 files changed, 71 insertions(+), 61 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ClassText.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt index 32d3efa85..4b515e1fb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt @@ -21,7 +21,7 @@ open class Member : RealmObject(), Avatar, BaseMainObject, Assignable { @PrimaryKey @SerializedName("_id") - override var id: String? = null + override var id: String = "" override var stats: Stats? = null var inbox: Inbox? = null override var preferences: MemberPreferences? = null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt index 06213f46b..827164115 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartySeekingFragment.kt @@ -19,7 +19,6 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Text -import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.runtime.Composable @@ -27,16 +26,11 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.fragment.app.viewModels @@ -51,11 +45,10 @@ import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.theme.HabiticaTheme import com.habitrpg.android.habitica.ui.viewmodels.BaseViewModel import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel -import com.habitrpg.android.habitica.ui.views.ClassIcon +import com.habitrpg.android.habitica.ui.views.ClassText import com.habitrpg.android.habitica.ui.views.ComposableAvatarView import com.habitrpg.android.habitica.ui.views.LoadingButton import com.habitrpg.android.habitica.ui.views.LoadingButtonState -import com.habitrpg.android.habitica.ui.views.getTranslatedClassName import com.habitrpg.android.habitica.ui.views.progress.HabiticaPullRefreshIndicator import com.habitrpg.common.habitica.helpers.launchCatching import dagger.hilt.android.AndroidEntryPoint @@ -125,41 +118,6 @@ class PartySeekingFragment : BaseFragment() { } } -@Composable -fun ClassText( - className : String?, - hasClass : Boolean, - fontSize : TextUnit, - modifier : Modifier = Modifier, - iconSize : Dp? = null -) { - if (!hasClass) return - val classColor = colorResource( - when (className) { - "warrior" -> R.color.text_red - "wizard" -> R.color.text_blue - "rogue" -> R.color.text_brand - "healer" -> R.color.text_yellow - else -> R.color.text_primary - } - ) - Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) { - ClassIcon( - className = className, - hasClass = true, - modifier = Modifier.size(iconSize ?: with(LocalDensity.current) { - fontSize.toDp() - }) - ) - Text( - getTranslatedClassName(LocalContext.current.resources, className), - fontSize = fontSize, - fontWeight = FontWeight.SemiBold, - color = classColor - ) - } -} - @Composable fun InviteButton( state : LoadingButtonState, @@ -177,7 +135,8 @@ fun InviteButton( fun PartySeekingListItem( user : Member, modifier : Modifier = Modifier, - onInvite : suspend (Member) -> InviteResponse? + inviteState : LoadingButtonState = LoadingButtonState.LOADING, + onInvite : (Member) -> Unit ) { Column( modifier @@ -242,20 +201,8 @@ fun PartySeekingListItem( ) } } - val scope = rememberCoroutineScope() - var inviteState : LoadingButtonState by remember { mutableStateOf(LoadingButtonState.CONTENT) } InviteButton(state = inviteState, modifier = Modifier.fillMaxWidth().padding(top=8.dp), onClick = { - scope.launchCatching({ - inviteState = LoadingButtonState.FAILED - }) { - inviteState = LoadingButtonState.LOADING - val response = onInvite(user) - inviteState = if (response != null) { - LoadingButtonState.SUCCESS - } else { - LoadingButtonState.FAILED - } - } + onInvite(user) }) } } @@ -269,6 +216,9 @@ fun PartySeekingView( val users : List by viewModel.seekingUsers val refreshing by viewModel.isRefreshing val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.retrieveUsers() }) + val scope = rememberCoroutineScope() + + val inviteStates = remember { mutableMapOf() } Box(modifier = modifier .fillMaxSize() @@ -293,8 +243,18 @@ fun PartySeekingView( } } items(users) { - PartySeekingListItem(user = it, modifier = Modifier.animateItemPlacement()) { member -> - return@PartySeekingListItem viewModel.inviteUser(member) + PartySeekingListItem(user = it, inviteState = inviteStates[it.id] ?: LoadingButtonState.LOADING, modifier = Modifier.animateItemPlacement()) { member -> + scope.launchCatching({ + inviteStates[member.id] = LoadingButtonState.FAILED + }) { + inviteStates[member.id] = LoadingButtonState.LOADING + val response = viewModel.inviteUser(member) + inviteStates[member.id] = if (response != null) { + LoadingButtonState.SUCCESS + } else { + LoadingButtonState.FAILED + } + } } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ClassText.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ClassText.kt new file mode 100644 index 000000000..98cb9f0e8 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ClassText.kt @@ -0,0 +1,50 @@ +package com.habitrpg.android.habitica.ui.views + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit +import com.habitrpg.android.habitica.R + +@Composable +fun ClassText( + className : String?, + hasClass : Boolean, + fontSize : TextUnit, + modifier : Modifier = Modifier, + iconSize : Dp? = null +) { + if (!hasClass) return + val classColor = colorResource( + when (className) { + "warrior" -> R.color.text_red + "wizard" -> R.color.text_blue + "rogue" -> R.color.text_brand + "healer" -> R.color.text_yellow + else -> R.color.text_primary + } + ) + Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) { + ClassIcon( + className = className, + hasClass = true, + modifier = Modifier.size(iconSize ?: with(LocalDensity.current) { + fontSize.toDp() + }) + ) + Text( + getTranslatedClassName(LocalContext.current.resources, className), + fontSize = fontSize, + fontWeight = FontWeight.SemiBold, + color = classColor + ) + } +} diff --git a/version.properties b/version.properties index d2013acd8..53c8a08a7 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ NAME=4.1.8 -CODE=5671 \ No newline at end of file +CODE=5681 \ No newline at end of file