diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml
index e1decdb78..8a6ddfd35 100644
--- a/Habitica/res/values/strings.xml
+++ b/Habitica/res/values/strings.xml
@@ -1270,6 +1270,8 @@
Edit assignees
Assign to...
Promote to Manager
+ Manager
+ Member List
- You
- You, %d other
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
index 5ccb1674d..7ef147f55 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
@@ -119,4 +119,5 @@ interface SocialRepository : BaseRepository {
fun getGroupMembership(id: String): Flow
fun getGroupMemberships(): Flow>
suspend fun blockMember(userID: String): List?
+ fun getMember(userID: String?): Flow
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
index a99a5fcae..33d407af2 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
@@ -40,6 +40,10 @@ class SocialRepositoryImpl(
return apiClient.blockMember(userID)
}
+ override fun getMember(userID: String?): Flow {
+ return localRepository.getMember(userID)
+ }
+
override fun getGroupMembership(id: String) = localRepository.getGroupMembership(userID, id)
override fun getGroupMemberships(): Flow> {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
index c40981364..7f712f980 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
@@ -54,4 +54,5 @@ interface SocialLocalRepository : BaseLocalRepository {
page: Int
)
fun saveInboxConversations(userID: String, conversations: List)
+ fun getMember(userID: String?): Flow
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
index c63e9094a..032948ad5 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
@@ -102,6 +102,15 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
}
}
+ override fun getMember(userID: String?): Flow {
+ return realm.where(Member::class.java)
+ .equalTo("id", userID)
+ .findAll()
+ .toFlow()
+ .filter { member -> member.isLoaded && member.isValid }
+ .map { member -> member.firstOrNull() }
+ }
+
override fun saveGroupMemberships(userID: String?, memberships: List) {
save(memberships)
if (userID != null) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/BuyRewardUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/BuyRewardUseCase.kt
index 617c50a8a..9bb470426 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/BuyRewardUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/BuyRewardUseCase.kt
@@ -11,7 +11,7 @@ class BuyRewardUseCase @Inject
constructor(
private val taskRepository: TaskRepository,
private val soundManager: SoundManager,
-) : FlowUseCase() {
+) : UseCase() {
override suspend fun run(requestValues: RequestValues): TaskScoringResult? {
val response = taskRepository.taskChecked(requestValues.user, requestValues.task, false, false, requestValues.notifyFunc)
@@ -23,5 +23,5 @@ constructor(
internal val user: User?,
val task: Task,
val notifyFunc: (TaskScoringResult) -> Unit
- ) : FlowUseCase.RequestValues
+ ) : UseCase.RequestValues
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt
index 1c2cf3fb7..b6f377caf 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt
@@ -7,7 +7,7 @@ import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity
import javax.inject.Inject
-class CheckClassSelectionUseCase @Inject constructor() : FlowUseCase() {
+class CheckClassSelectionUseCase @Inject constructor() : UseCase() {
override suspend fun run(requestValues: RequestValues) {
val user = requestValues.user
@@ -42,5 +42,5 @@ class CheckClassSelectionUseCase @Inject constructor() : FlowUseCase() {
+ UseCase() {
override suspend fun run(requestValues: RequestValues) {
val data = requestValues.data
@@ -49,5 +49,5 @@ constructor(private val soundManager: SoundManager):
val context: AppCompatActivity,
val snackbarTargetView: ViewGroup,
val showQuestItems: Boolean
- ) : FlowUseCase.RequestValues
+ ) : UseCase.RequestValues
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt
index 5ae6bf77b..d121d676b 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt
@@ -20,7 +20,7 @@ import javax.inject.Inject
class FeedPetUseCase @Inject
constructor(
private val inventoryRepository: InventoryRepository,
-) : FlowUseCase() {
+) : UseCase() {
override suspend fun run(requestValues: FeedPetUseCase.RequestValues): FeedResponse? {
val feedResponse = inventoryRepository.feedPet(requestValues.pet, requestValues.food)
(requestValues.context as? SnackbarActivity)?.showSnackbar(content = feedResponse?.message)
@@ -77,5 +77,5 @@ constructor(
}
class RequestValues(val pet: Pet, val food: Food, val context: Context) :
- FlowUseCase.RequestValues
+ UseCase.RequestValues
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt
index b2cbdbb50..7b38dd5e4 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt
@@ -20,7 +20,7 @@ import javax.inject.Inject
class HatchPetUseCase @Inject
constructor(
- private val inventoryRepository: InventoryRepository) : FlowUseCase() {
+ private val inventoryRepository: InventoryRepository) : UseCase() {
override suspend fun run(requestValues: RequestValues): Items? {
return inventoryRepository.hatchPet(requestValues.egg, requestValues.potion) {
val petWrapper = View.inflate(requestValues.context, R.layout.pet_imageview, null) as? FrameLayout
@@ -52,5 +52,5 @@ constructor(
}
}
- class RequestValues(val potion: HatchingPotion, val egg: Egg, val context: Context) : FlowUseCase.RequestValues
+ class RequestValues(val potion: HatchingPotion, val egg: Egg, val context: Context) : UseCase.RequestValues
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt
index 2f0e7b2c6..00910fddb 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt
@@ -20,7 +20,7 @@ class LevelUpUseCase @Inject
constructor(
private val soundManager: SoundManager,
private val checkClassSelectionUseCase: CheckClassSelectionUseCase
-) : FlowUseCase() {
+) : UseCase() {
override suspend fun run(requestValues: RequestValues): Stats? {
soundManager.loadAndPlayAudio(SoundManager.SoundLevelUp)
@@ -99,7 +99,7 @@ constructor(
val level: Int?,
val activity: BaseActivity,
val snackbarTargetView: ViewGroup
- ) : FlowUseCase.RequestValues {
+ ) : UseCase.RequestValues {
val newLevel: Int = level ?: 0
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt
index 658bcd66b..b63f9f7f7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/NotifyUserUseCase.kt
@@ -27,7 +27,7 @@ class NotifyUserUseCase @Inject
constructor(
private val levelUpUseCase: LevelUpUseCase,
private val userRepository: UserRepository
-) : FlowUseCase() {
+) : UseCase() {
override suspend fun run(requestValues: RequestValues): Stats? {
if (requestValues.user == null) {
@@ -57,7 +57,7 @@ constructor(
val questDamage: Double?,
val hasLeveledUp: Boolean?,
val level: Int?
- ) : FlowUseCase.RequestValues
+ ) : UseCase.RequestValues
companion object {
val formatter = NumberFormat.getInstance().apply {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/UseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/UseCase.kt
index 82222ccf0..0d5407580 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/UseCase.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/UseCase.kt
@@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.interactors
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-abstract class FlowUseCase {
+abstract class UseCase {
protected abstract suspend fun run(requestValues: Q): T
suspend fun callInteractor(requestValues: Q): T {
return withContext(Dispatchers.Main) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
index 7ad85dcec..aace8c7c4 100755
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt
@@ -16,6 +16,9 @@ import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.ActionBarDrawerToggle
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
import androidx.core.os.bundleOf
import androidx.core.view.children
import androidx.drawerlayout.widget.DrawerLayout
@@ -240,7 +243,9 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
HabiticaTheme {
AppHeaderView(viewModel.userViewModel) {
showAsBottomSheet { onClose ->
- GroupPlanMemberList(it, {
+ val group by viewModel.userViewModel.currentTeamPlanGroup.collectAsState(null)
+ val members by viewModel.userViewModel.currentTeamPlanMembers.observeAsState()
+ GroupPlanMemberList(members, group, {
onClose()
FullProfileActivity.open(it)
}, { member ->
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt
index b8d9cd0e5..ee18c4334 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt
@@ -18,6 +18,7 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
@@ -42,25 +43,35 @@ import androidx.lifecycle.asLiveData
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
+import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.data.TaskRepository
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.TaskDescriptionBuilder
+import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
import com.habitrpg.android.habitica.ui.viewmodels.BaseViewModel
import com.habitrpg.android.habitica.ui.views.CompletedAt
import com.habitrpg.android.habitica.ui.views.UserRow
import com.habitrpg.shared.habitica.models.tasks.TaskType
+import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class TaskSummaryViewModel(val taskId: String) : BaseViewModel() {
@Inject
lateinit var taskRespository: TaskRepository
+ @Inject
+ lateinit var socialRepository: SocialRepository
+
val task = taskRespository.getTask(taskId).asLiveData()
override fun inject(component: UserComponent) {
component.inject(this)
}
+ fun getMember(userID: String?): Flow {
+ return socialRepository.getMember(userID)
+ }
+
@Suppress("UNCHECKED_CAST")
class Factory(private val taskID: String) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
@@ -230,8 +241,9 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
modifier = titleModifier.padding(bottom = 4.dp)
)
for (item in task?.group?.assignedUsersDetail ?: emptyList()) {
+ val member = viewModel.getMember(item.assignedUserID).collectAsState(null)
UserRow(
- item.assignedUsername ?: "", Modifier
+ item.assignedUsername ?: "", member.value, Modifier
.padding(vertical = 4.dp)
.background(
colorResource(
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/theme/HabiticaTheme.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/theme/HabiticaTheme.kt
index 1e18e3b43..9cc4259d1 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/theme/HabiticaTheme.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/theme/HabiticaTheme.kt
@@ -135,7 +135,7 @@ object HabiticaTheme {
contentBackgroundOffset = Color(context.getThemeColor(R.attr.colorContentBackgroundOffset)),
textPrimary = Color(context.getThemeColor(R.attr.textColorPrimary)),
textSecondary = Color(context.getThemeColor(R.attr.textColorSecondary)),
- textTertiary = Color(context.getThemeColor(R.attr.colorTertiary)),
+ textTertiary = Color(ContextCompat.getColor(context, R.color.text_ternary)),
textDimmed = Color(ContextCompat.getColor(context, R.color.text_dimmed)),
)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt
index 451484c8b..71b6d276a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt
@@ -44,7 +44,6 @@ import androidx.compose.ui.unit.sp
import androidx.core.os.bundleOf
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.helpers.MainNavigationController
-import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@@ -72,7 +71,7 @@ fun UserLevelText(user: User) {
@Composable
fun AppHeaderView(
viewModel: MainUserViewModel,
- onMemberRowClicked: (List) -> Unit
+ onMemberRowClicked: () -> Unit
) {
val user by viewModel.user.observeAsState(null)
val teamPlan by viewModel.currentTeamPlan.collectAsState(null)
@@ -181,7 +180,7 @@ fun AppHeaderView(
colorResource(R.color.window_background)
)
.clickable {
- teamPlanMembers?.let { onMemberRowClicked(it) }
+ onMemberRowClicked()
}
) {
for (member in teamPlanMembers?.filter { it.id != user?.id }?.take(6) ?: emptyList()) {
@@ -205,11 +204,20 @@ fun AppHeaderView(
ClassIcon(className = user?.stats?.habitClass, hasClass = user?.hasClass ?: false, modifier = Modifier.padding(4.dp))
user?.let { UserLevelText(it) }
Spacer(Modifier.weight(1f))
- user?.hourglassCount?.toDouble()
- ?.let { CurrencyText("hourglasses", it, modifier = Modifier.padding(end = 12.dp)) }
+ if (user?.isSubscribed == true) {
+ user?.hourglassCount?.toDouble()
+ ?.let {
+ CurrencyText(
+ "hourglasses",
+ it,
+ modifier = Modifier.padding(end = 12.dp).clickable {
+ MainNavigationController.navigate(R.id.subscriptionPurchaseActivity)
+ })
+ }
+ }
CurrencyText("gold", user?.stats?.gp ?: 0.0, modifier = Modifier.padding(end = 12.dp))
CurrencyText("gems", user?.gemCount?.toDouble() ?: 0.0, modifier = Modifier.clickable {
- MainNavigationController.navigate(R.id.gemPurchaseActivity, bundleOf(Pair("openSubscription", false)))
+ MainNavigationController.navigate(R.id.gemPurchaseActivity)
})
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BottomSheetUtils.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BottomSheetUtils.kt
index 9d3a399e6..a4424d872 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BottomSheetUtils.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BottomSheetUtils.kt
@@ -74,21 +74,24 @@ private fun BottomSheetWrapper(
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
var isSheetOpened by remember { mutableStateOf(false) }
+ val radius = 20.dp
ModalBottomSheetLayout(
sheetBackgroundColor = Color.Transparent,
sheetState = modalBottomSheetState,
+ sheetShape = RoundedCornerShape(topStart = radius, topEnd = radius),
sheetContent = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
+ .padding(horizontal = 4.dp)
.border(
2.dp,
colorResource(R.color.window_background),
- RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)
+ RoundedCornerShape(topStart = radius, topEnd = radius)
)
.background(
MaterialTheme.colors.background,
- RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)
+ RoundedCornerShape(topStart = radius, topEnd = radius)
)
.padding(vertical = 8.dp)
) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CurrencyText.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CurrencyText.kt
index 69900db83..9c49aac8a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CurrencyText.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CurrencyText.kt
@@ -23,7 +23,7 @@ fun CurrencyText(
decimals: Int = 2,
minForAbbrevation: Int = 0
) {
- Row(verticalAlignment = Alignment.CenterVertically) {
+ Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
when (currency) {
"gold" -> HabiticaIconsHelper.imageOfGold()
"gems" -> HabiticaIconsHelper.imageOfGem()
@@ -39,8 +39,7 @@ fun CurrencyText(
else -> colorResource(R.color.text_primary)
},
fontSize = 12.sp,
- fontWeight = FontWeight.SemiBold,
- modifier = modifier
+ fontWeight = FontWeight.SemiBold
)
}
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/GroupPlanMemberList.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/GroupPlanMemberList.kt
index 034e03f6b..95c70c75e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/GroupPlanMemberList.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/GroupPlanMemberList.kt
@@ -14,18 +14,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
-import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
-import androidx.compose.ui.platform.LocalContext
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.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@@ -34,24 +31,52 @@ import androidx.compose.ui.unit.sp
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.models.auth.LocalAuthentication
import com.habitrpg.android.habitica.models.members.Member
+import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.models.user.Authentication
import com.habitrpg.android.habitica.models.user.Profile
import com.habitrpg.android.habitica.models.user.Stats
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
-import com.habitrpg.common.habitica.extensions.getThemeColor
import kotlin.random.Random
@Composable
fun GroupPlanMemberList(
- members: List,
+ members: List?,
+ group: Group?,
onMemberClicked: (String) -> Unit,
onMoreClicked: (Member) -> Unit
) {
LazyColumn {
- for (member in members) {
+ item {
+ Text(stringResource(R.string.member_list),
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Medium,
+ color = HabiticaTheme.colors.textTertiary,
+ textAlign = TextAlign.Center,
+ modifier = Modifier.fillMaxWidth()
+ .padding(bottom = 20.dp)
+ )
+ }
+ for (member in members?.sortedWith(compareByDescending {
+ group?.isLeader(
+ it.id ?: ""
+ )
+ }.thenByDescending {
+ group?.isManager(
+ it.id ?: ""
+ )
+ }.thenBy { it.username }) ?: emptyList()) {
item {
+ val role = if (group?.isLeader(member.id ?: "") == true) {
+ stringResource(R.string.owner)
+ } else if (group?.isManager(member.id ?: "") == true) {
+ stringResource(R.string.manager)
+ } else {
+ stringResource(R.string.member)
+
+ }
MemberItem(
member,
+ role,
onMemberClicked,
onMoreClicked,
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
@@ -64,6 +89,7 @@ fun GroupPlanMemberList(
@Composable
fun MemberItem(
member: Member,
+ role: String,
onMemberClicked: (String) -> Unit,
onMoreClicked: (Member) -> Unit,
modifier: Modifier = Modifier
@@ -77,23 +103,14 @@ fun MemberItem(
member.id?.let { onMemberClicked(it) }
}
) {
- TextButton(
- onClick = { onMoreClicked(member) }, modifier = Modifier
- .size(32.dp)
- .background(
- Color(LocalContext.current.getThemeColor(R.attr.colorAccent)),
- WobblyCircle
- )
- .align(Alignment.TopEnd)
- ) {
- Image(painterResource(R.drawable.menu_messages), null)
- }
Row(
- horizontalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.padding(14.dp)
+ horizontalArrangement = Arrangement.spacedBy(10.dp),
+ modifier = Modifier.padding(8.dp)
) {
- ComposableAvatarView(avatar = member, modifier = Modifier.size(94.dp, 98.dp))
- Column(verticalArrangement = Arrangement.SpaceBetween, modifier = Modifier.height(100.dp)) {
+ ComposableAvatarView(avatar = member, modifier = Modifier
+ .padding(6.dp)
+ .size(94.dp, 98.dp))
+ Column(verticalArrangement = Arrangement.SpaceBetween, modifier = Modifier.height(104.dp).padding(end = 6.dp)) {
Text(
member.displayName,
fontWeight = FontWeight.SemiBold,
@@ -101,17 +118,16 @@ fun MemberItem(
color = HabiticaTheme.colors.textPrimary
)
Row(
- horizontalArrangement = Arrangement.spacedBy(4.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
member.formattedUsername ?: "",
- color = HabiticaTheme.colors.textSecondary
+ color = HabiticaTheme.colors.textTertiary
)
Spacer(
Modifier
.weight(1.0f)
- .background(Color.Red)
)
ClassIcon(
member.stats?.habitClass,
@@ -126,14 +142,16 @@ fun MemberItem(
barColor = HabiticaTheme.colors.contentBackgroundOffset,
value = member.stats?.hp ?: 0.0,
maxValue = (member.stats?.maxHealth ?: 0).toDouble(),
- displayCompact = true
+ displayCompact = true,
+ barHeight = 5.dp
)
LabeledBar(
color = colorResource(R.color.xpColor),
barColor = HabiticaTheme.colors.contentBackgroundOffset,
value = member.stats?.exp ?: 0.0,
maxValue = (member.stats?.toNextLevel ?: 0).toDouble(),
- displayCompact = true
+ displayCompact = true,
+ barHeight = 5.dp
)
if (member.hasClass) {
LabeledBar(
@@ -141,7 +159,8 @@ fun MemberItem(
barColor = HabiticaTheme.colors.contentBackgroundOffset,
value = member.stats?.mp ?: 0.0,
maxValue = (member.stats?.maxMP ?: 0).toDouble(),
- displayCompact = true
+ displayCompact = true,
+ barHeight = 5.dp
)
}
Row(horizontalArrangement = Arrangement.SpaceBetween) {
@@ -149,11 +168,12 @@ fun MemberItem(
stringResource(R.string.level_unabbreviated, member.stats?.lvl ?: 0),
fontSize = 14.sp,
fontWeight = FontWeight.Normal,
- color = HabiticaTheme.colors.textPrimary
+ color = HabiticaTheme.colors.textTertiary
)
+ Spacer(Modifier.weight(1f))
Text(
- "", fontWeight = FontWeight.SemiBold, fontSize = 14.sp,
- color = HabiticaTheme.colors.textPrimary
+ role, fontWeight = FontWeight.SemiBold, fontSize = 14.sp,
+ color = HabiticaTheme.colors.textSecondary
)
}
}
@@ -197,5 +217,5 @@ private class MemberProvider : PreviewParameterProvider {
@Composable
@Preview
private fun Preview(@PreviewParameter(MemberProvider::class) member: Member) {
- MemberItem(member = member, onMemberClicked = {}, onMoreClicked = {})
+ MemberItem(member = member, role = "Manager", onMemberClicked = {}, onMoreClicked = {})
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/LabeledBar.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/LabeledBar.kt
index cd7179d3f..3a91edaba 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/LabeledBar.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/LabeledBar.kt
@@ -29,6 +29,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.habitrpg.android.habitica.R
@@ -44,7 +45,8 @@ fun LabeledBar(
barColor: Color = HabiticaTheme.colors.windowBackground,
value: Double,
maxValue: Double,
- displayCompact: Boolean,
+ displayCompact: Boolean = false,
+ barHeight: Dp = 8.dp,
disabled: Boolean = false
) {
val cleanedMaxVlaue = java.lang.Double.max(1.0, maxValue)
@@ -72,7 +74,7 @@ fun LabeledBar(
Modifier
.fillMaxWidth()
.clip(CircleShape)
- .height(8.dp),
+ .height(barHeight),
backgroundColor = barColor,
color = color
)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/UserRow.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/UserRow.kt
index 09e293326..164798779 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/UserRow.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/UserRow.kt
@@ -1,27 +1,51 @@
package com.habitrpg.android.habitica.ui.views
-import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import com.habitrpg.shared.habitica.models.Avatar
@Composable
fun UserRow(
username: String,
+ avatar: Avatar?,
modifier: Modifier = Modifier,
extraContent: @Composable (() -> Unit)? = null,
endContent: @Composable (() -> Unit)? = null,
color: Color? = null
) {
- Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = modifier.fillMaxWidth()) {
+ Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier.fillMaxWidth()) {
+ Box(modifier = Modifier
+ .padding(end = 12.dp)
+ .clip(CircleShape)
+ .size(40.dp)
+ .padding(end = 12.dp, top = if (avatar?.currentMount?.isNotBlank() == true) 24.dp else 12.dp)) {
+ if (avatar != null) {
+ ComposableAvatarView(
+ avatar = avatar,
+ Modifier
+ .size(96.dp)
+ .requiredSize(96.dp)
+ )
+ }
+ }
+
Column {
Text(
"@$username",
@@ -33,6 +57,7 @@ fun UserRow(
extraContent()
}
}
+ Spacer(Modifier.weight(1f))
if (endContent != null) {
endContent()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsView.kt
index f1fe3e916..23545919f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsView.kt
@@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextButton
@@ -122,7 +121,7 @@ fun StatsViewPreview() {
levelValue = 10,
equipmentValue = 5,
buffValue = 4,
- allocatedValue = 8,
+ allocatedValue = 20,
canAllocate = true
) {}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignSheet.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignSheet.kt
index c8d2d6c58..645595bdd 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignSheet.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignSheet.kt
@@ -94,6 +94,7 @@ fun AssignSheet(
}
UserRow(
username = member.displayName,
+ avatar = member,
color = colorResource(R.color.text_primary),
extraContent = {
Text(
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignedView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignedView.kt
index 0e0669568..18ca09270 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignedView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/AssignedView.kt
@@ -46,7 +46,9 @@ fun AssignedView(
.fillMaxWidth()
for (assignable in assigned) {
UserRow(
- username = assignable.identifiableName, modifier = rowModifier,
+ username = assignable.identifiableName,
+ avatar = assignable.avatar,
+ modifier = rowModifier,
color = color,
extraContent = {
completedAt[assignable.id]?.let { CompletedAt(completedAt = it) }
diff --git a/version.properties b/version.properties
index 1dc1c6bf1..18b1b60b7 100644
--- a/version.properties
+++ b/version.properties
@@ -1,2 +1,2 @@
NAME=4.1
-CODE=4781
\ No newline at end of file
+CODE=4791
\ No newline at end of file