Fix many small issues

This commit is contained in:
Phillip Thelen 2022-12-21 14:52:36 +01:00
parent 5ce0425c8a
commit 3cfdf48fe4
26 changed files with 1241 additions and 1113 deletions

View file

@ -63,7 +63,7 @@
android:maxLines="1"
android:singleLine="true"
android:layout_alignParentStart="true"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
style="@style/ToolbarTitle"
tools:text="Habitica"
android:background="@drawable/teams_title_bg"
android:paddingHorizontal="@dimen/spacing_large"

View file

@ -17,6 +17,7 @@
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="@style/Toolbar"
style="@style/ToolbarTitleStyle"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>

View file

@ -171,8 +171,9 @@
android:layout_height="wrap_content"
android:text="@string/months_subscribed"
android:gravity="center"
android:fontFamily="sans-serif-medium"
android:textColor="@color/text_secondary"/>
android:fontFamily="sans-serif"
android:textStyle="bold"
android:textSize="12sp"/>
</LinearLayout>
<LinearLayout
@ -197,8 +198,9 @@
android:layout_height="wrap_content"
android:text="@string/monthly_gem_cap"
android:gravity="center"
android:fontFamily="sans-serif-medium"
android:textColor="@color/text_secondary"/>
android:fontFamily="sans-serif"
android:textStyle="bold"
android:textSize="12sp"/>
</LinearLayout>
</LinearLayout>
@ -210,18 +212,20 @@
android:layout_height="wrap_content">
<ImageView
android:layout_width="60dp"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_centerVertical="true"
android:layout_marginStart="2dp"
android:scaleType="center"
android:src="@drawable/hourglass_fancy_left" />
<ImageView
android:layout_width="60dp"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:scaleType="center"
android:src="@drawable/hourglass_fancy_right" />
<TextView
@ -239,7 +243,9 @@
android:layout_below="@id/next_hourglass_textview"
android:layout_centerHorizontal="true"
android:text="@string/next_hourglass"
android:fontFamily="sans-serif-medium"
android:fontFamily="sans-serif"
android:textStyle="bold"
android:textSize="12sp"
android:textColor="@color/text_secondary"/>
</RelativeLayout>

View file

@ -124,6 +124,17 @@
android:id="@+id/openEquipmentDetail"
app:destination="@id/equipmentDetailFragment" />
</fragment>
<fragment
android:id="@+id/equipmentOverviewFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.inventory.customization.EquipmentOverviewFragment"
android:label="@string/sidebar_equipment" >
<action
android:id="@+id/openAvatarDetail"
app:destination="@id/avatarCustomizationFragment" />
<action
android:id="@+id/openEquipmentDetail"
app:destination="@id/equipmentDetailFragment" />
</fragment>
<fragment
android:id="@+id/itemsFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemsFragment"

View file

@ -2,6 +2,7 @@
<resources>
<color name="brand">@color/brand_400</color>
<color name="color_accent">@color/brand_400</color>
<color name="text_title">@color/white</color>
<color name="text_primary">@color/gray_600</color>
<color name="text_secondary">@color/gray_500</color>
<color name="text_ternary">@color/gray_400</color>

View file

@ -1287,6 +1287,12 @@
<string name="status">Status</string>
<string name="regular_access">Regular Access</string>
<string name="message_flagged">Message flagged %d times.</string>
<string name="amazon">Amazon</string>
<string name="apple_pay">Apple Pay</string>
<string name="google_pay">Google Pay</string>
<string name="paypal">PayPal</string>
<string name="stripe_payment">Stripe</string>
<string name="shadow_muted_hidden">Shadow muted, hidden</string>
<plurals name="you_x_others">
<item quantity="zero">You</item>
<item quantity="one">You, %d other</item>

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,10 @@ object MainNavigationController {
this.controllerReference = WeakReference(navController)
}
fun updateLabel(destinationID: Int, label: String) {
navController?.findDestination(destinationID)?.label = label
}
fun navigate(transactionId: Int, args: Bundle? = null) {
if (abs((lastNavigation?.time ?: 0) - Date().time) > 500) {
lastNavigation = Date()

View file

@ -158,7 +158,6 @@ abstract class BaseActivity : AppCompatActivity() {
"green" -> R.style.MainAppTheme_Green
"teal" -> R.style.MainAppTheme_Teal
"blue" -> R.style.MainAppTheme_Blue
"taskform" -> R.style.MainAppTheme_TaskForm
else -> R.style.MainAppTheme
}
)

View file

@ -127,7 +127,7 @@ class FullProfileActivity : BaseActivity() {
binding.blockedDisclaimerView.visibility =
if (isUserBlocked()) View.VISIBLE else View.GONE
isModerator = it?.hasPermission(Permission.USER_SUPPORT) == true
isModerator = it?.hasPermission(Permission.MODERATOR) == true
binding.adminStatusView.isVisible = isModerator
if (isModerator) {
val member = socialRepository.retrieveMember(userID, true)

View file

@ -428,7 +428,14 @@ class NavigationDrawerFragment : DialogFragment() {
HabiticaDrawerItem(
R.id.avatarOverviewFragment,
SIDEBAR_AVATAR,
context.getString(R.string.sidebar_avatar_equipment)
context.getString(R.string.sidebar_avatar)
)
)
items.add(
HabiticaDrawerItem(
R.id.equipmentOverviewFragment,
SIDEBAR_EQUIPMENT,
context.getString(R.string.sidebar_equipment)
)
)
items.add(

View file

@ -34,7 +34,7 @@ import com.habitrpg.android.habitica.ui.views.EquipmentOverviewView
import com.habitrpg.android.habitica.ui.views.SegmentedControl
import javax.inject.Inject
class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>(),
open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>(),
AdapterView.OnItemSelectedListener {
@Inject
@ -42,6 +42,8 @@ class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>
override var binding: FragmentComposeScrollingBinding? = null
protected var showCustomization = true
override fun createBinding(
inflater: LayoutInflater,
container: ViewGroup?
@ -59,7 +61,9 @@ class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
HabiticaTheme {
AvatarOverviewView(userViewModel, { type, category ->
AvatarOverviewView(userViewModel,
showCustomization, !showCustomization,
{ type, category ->
displayCustomizationFragment(type, category)
}, { type, equipped, isCostume ->
displayEquipmentFragment(type, equipped, isCostume)
@ -101,6 +105,8 @@ class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>
@Composable
fun AvatarOverviewView(userViewModel: MainUserViewModel,
showCustomization: Boolean = true,
showEquipment: Boolean = true,
onCustomizationTap: (String, String?) -> Unit,
onEquipmentTap: (String, String?, Boolean) -> Unit
) {
@ -109,65 +115,82 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
Modifier
.padding(horizontal = 8.dp)
.padding(bottom = 16.dp)) {
Row(Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
verticalAlignment = Alignment.CenterVertically) {
Text(
stringResource(R.string.avatar_size),
style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary
)
Spacer(modifier = Modifier.weight(1f))
SegmentedControl(items = listOf(stringResource(R.string.avatar_size_slim), stringResource(R.string.avatar_size_broad
)), defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1, onItemSelection = {
userViewModel.updateUser("preferences.size", if (it == 0) "slim" else "broad")
})
if (showCustomization) {
Row(
Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
stringResource(R.string.avatar_size),
style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary
)
Spacer(modifier = Modifier.weight(1f))
SegmentedControl(items = listOf(
stringResource(R.string.avatar_size_slim), stringResource(
R.string.avatar_size_broad
)
),
defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1,
onItemSelection = {
userViewModel.updateUser(
"preferences.size",
if (it == 0) "slim" else "broad"
)
})
}
AvatarCustomizationOverviewView(user?.preferences, onCustomizationTap)
}
AvatarCustomizationOverviewView(user?.preferences, onCustomizationTap)
Row(
Modifier
.padding(horizontal = 12.dp)
.padding(top = 15.dp),
verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.equipped), style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary)
Spacer(modifier = Modifier.weight(1f))
Text(
stringResource(R.string.equip_automatically),
style = HabiticaTheme.typography.body2,
color = HabiticaTheme.colors.textPrimary
)
Switch(checked = user?.preferences?.autoEquip == true, onCheckedChange = {
userViewModel.updateUser("preferences.autoEquip", it)
})
}
EquipmentOverviewView(user?.items?.gear?.equipped, { type, equipped ->
onEquipmentTap(type, equipped, false)
})
Row(
Modifier
.padding(horizontal = 12.dp)
.padding(top = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
stringResource(R.string.costume),
style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary
)
Spacer(modifier = Modifier.weight(1f))
Text(
stringResource(R.string.wear_costume),
style = HabiticaTheme.typography.body2,
color = HabiticaTheme.colors.textPrimary
)
Switch(checked = user?.preferences?.costume == true, onCheckedChange = {
userViewModel.updateUser("preferences.costume", it)
})
}
AnimatedVisibility(visible = user?.preferences?.costume == true) {
EquipmentOverviewView(user?.items?.gear?.costume, { type, equipped ->
onEquipmentTap(type, equipped, true)
if (showEquipment) {
Row(
Modifier
.padding(horizontal = 12.dp)
.padding(top = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
stringResource(R.string.equipped), style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary
)
Spacer(modifier = Modifier.weight(1f))
Text(
stringResource(R.string.equip_automatically),
style = HabiticaTheme.typography.body2,
color = HabiticaTheme.colors.textPrimary
)
Switch(checked = user?.preferences?.autoEquip == true, onCheckedChange = {
userViewModel.updateUser("preferences.autoEquip", it)
})
}
EquipmentOverviewView(user?.items?.gear?.equipped, { type, equipped ->
onEquipmentTap(type, equipped, false)
})
Row(
Modifier
.padding(horizontal = 12.dp)
.padding(top = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
stringResource(R.string.costume),
style = HabiticaTheme.typography.subtitle2,
color = HabiticaTheme.colors.textSecondary
)
Spacer(modifier = Modifier.weight(1f))
Text(
stringResource(R.string.wear_costume),
style = HabiticaTheme.typography.body2,
color = HabiticaTheme.colors.textPrimary
)
Switch(checked = user?.preferences?.costume == true, onCheckedChange = {
userViewModel.updateUser("preferences.costume", it)
})
}
AnimatedVisibility(visible = user?.preferences?.costume == true) {
EquipmentOverviewView(user?.items?.gear?.costume, { type, equipped ->
onEquipmentTap(type, equipped, true)
})
}
}
}
}

View file

@ -0,0 +1,10 @@
package com.habitrpg.android.habitica.ui.fragments.inventory.customization
import android.os.Bundle
class EquipmentOverviewFragment : AvatarOverviewFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
showCustomization = false
super.onCreate(savedInstanceState)
}
}

View file

@ -26,6 +26,7 @@ import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding
import com.habitrpg.android.habitica.extensions.setTintWith
import com.habitrpg.android.habitica.helpers.AmplitudeManager
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.launchCatching
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
@ -420,6 +421,7 @@ class TasksFragment : BaseMainFragment<FragmentViewpagerBinding>(), SearchView.O
private fun updateBoardDisplay() {
if (viewModel.ownerTitle.isNotBlank()) {
activity?.title = viewModel.ownerTitle
MainNavigationController.updateLabel(R.id.tasksFragment, viewModel.ownerTitle.toString())
}
viewModel.userViewModel.currentTeamPlan.value = viewModel.teamPlans[viewModel.ownerID.value]
lifecycleScope.launchCatching {

View file

@ -212,7 +212,11 @@ class ChatRecyclerMessageViewHolder(
}
if ((chatMessage?.flagCount ?: 0) > 0) {
binding.flagCountTextview.text = context.getString(R.string.message_flagged, (chatMessage?.flagCount ?: 0))
binding.flagCountTextview.text = if (chatMessage?.flagCount == 10) {
context.getString(R.string.shadow_muted_hidden)
} else {
context.resources.getQuantityString(R.plurals.flagged_count, (chatMessage?.flagCount ?: 0))
}
binding.flagCountTextview.isVisible = true
if (chatMessage?.flagCount == 1) {
binding.flagCountTextview.setTextColor(ContextCompat.getColor(context, R.color.text_orange))

View file

@ -228,20 +228,33 @@ fun AppHeaderView(
ClassIcon(className = user?.stats?.habitClass, hasClass = user?.hasClass ?: false, modifier = Modifier.padding(4.dp))
user?.let { UserLevelText(it) }
Spacer(Modifier.weight(1f))
if (user is User && user.isSubscribed) {
if (user is User) {
if (user.isSubscribed) {
CurrencyText(
"hourglasses",
user.hourglassCount.toDouble(),
modifier = Modifier
.padding(end = 12.dp)
.clickable {
MainNavigationController.navigate(R.id.subscriptionPurchaseActivity)
}, decimals = 0
)
}
CurrencyText(
"hourglasses",
user.hourglassCount.toDouble(),
modifier = Modifier
.padding(end = 12.dp)
.clickable {
MainNavigationController.navigate(R.id.subscriptionPurchaseActivity)
}, decimals = 0)
"gold",
user?.stats?.gp ?: 0.0,
modifier = Modifier.padding(end = 12.dp),
decimals = 0
)
CurrencyText(
"gems",
user?.gemCount?.toDouble() ?: 0.0,
modifier = Modifier.clickable {
MainNavigationController.navigate(R.id.gemPurchaseActivity)
},
decimals = 0
)
}
CurrencyText("gold", user?.stats?.gp ?: 0.0, modifier = Modifier.padding(end = 12.dp), decimals = 0)
CurrencyText("gems", user?.gemCount?.toDouble() ?: 0.0, modifier = Modifier.clickable {
MainNavigationController.navigate(R.id.gemPurchaseActivity)
}, decimals = 0)
}
}
}

View file

@ -22,7 +22,7 @@ fun CurrencyText(
currency: String,
value: Double,
modifier: Modifier = Modifier,
decimals: Int = 2,
decimals: Int = 0,
minForAbbrevation: Int = 0,
animated: Boolean = true
) {

View file

@ -192,10 +192,16 @@ fun AvatarCustomizationOverviewView(
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
OverviewItem(
stringResource(R.string.avatar_wheelchair),
preferences?.chair?.let { if (it.startsWith("handleless")) "chair_$it" else it })
preferences?.chair?.let { if (it.startsWith("handleless")) "chair_$it" else it },
Modifier.clickable {
onCustomizationTap("chair", null)
})
OverviewItem(
stringResource(R.string.avatar_background),
preferences?.background.let { "background_$it" })
preferences?.background.let { "background_$it" },
Modifier.clickable {
onCustomizationTap("background", null)
})
Box(Modifier.size(70.dp))
Box(Modifier.size(70.dp))
}

View file

@ -65,6 +65,7 @@ class HabiticaBottomNavigationView @JvmOverloads constructor(
set(value) {
if (field == value) return
field = value
binding.addButton.isEnabled = value
val animator = ObjectAnimator.ofFloat(0f, 1.0f)
if (field) {
binding.addButtonBackground.animate()

View file

@ -79,11 +79,26 @@ class SubscriptionDetailsView : LinearLayout {
}
when (plan.paymentMethod) {
"Amazon Payments" -> binding.paymentProcessorImageView.setImageResource(R.drawable.payment_amazon)
"Apple" -> binding.paymentProcessorImageView.setImageResource(R.drawable.payment_apple)
"Google" -> binding.paymentProcessorImageView.setImageResource(R.drawable.payment_google)
"PayPal" -> binding.paymentProcessorImageView.setImageResource(R.drawable.payment_paypal)
"Stripe" -> binding.paymentProcessorImageView.setImageResource(R.drawable.payment_stripe)
"Amazon Payments" -> {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_amazon)
binding.subscriptionPaymentMethodTextview.text = context.getString(R.string.amazon)
}
"Apple" -> {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_apple)
binding.subscriptionPaymentMethodTextview.text = context.getString(R.string.apple_pay)
}
"Google" -> {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_google)
binding.subscriptionPaymentMethodTextview.text = context.getString(R.string.google_pay)
}
"PayPal" -> {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_paypal)
binding.subscriptionPaymentMethodTextview.text = context.getString(R.string.paypal)
}
"Stripe" -> {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_stripe)
binding.subscriptionPaymentMethodTextview.text = context.getString(R.string.stripe_payment)
}
else -> {
if (plan.isGiftedSub) {
binding.paymentProcessorImageView.setImageResource(R.drawable.payment_gift)

View file

@ -84,7 +84,7 @@ private fun HabitScoringSelection(
if (it) Color(context.getThemeColor(R.attr.colorTintedBackground)) else colorResource(R.color.text_dimmed)
}
val textColor = selectedState.animateColor {
if (it) MaterialTheme.colors.primary else colorResource(R.color.text_secondary)
if (it) MaterialTheme.colors.primary else colorResource(R.color.text_ternary)
}
val borderColor = selectedState.animateColor {
if (it) MaterialTheme.colors.primary else colorResource(R.color.text_dimmed)

View file

@ -82,7 +82,7 @@ private fun TaskDifficultySelection(
if (it) Color(context.getThemeColor(R.attr.colorTintedBackground)) else MaterialTheme.colors.primary
}
val textColor = selectedState.animateColor {
if (it) MaterialTheme.colors.primary else colorResource(R.color.text_secondary)
if (it) MaterialTheme.colors.primary else colorResource(R.color.text_ternary)
}
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(6.dp), modifier = modifier) {
Box(

View file

@ -12,7 +12,7 @@ object NumberAbbreviator {
}
fun abbreviate(context: Context?, number: Double, numberOfDecimals: Int = 2, minForAbbrevation: Int = 0): String {
val decimalCount = if (number > -1 && number < 1 && numberOfDecimals == 0) 1 else numberOfDecimals
val decimalCount = if (number != 0.0 && number > -1 && number < 1 && numberOfDecimals == 0) 1 else numberOfDecimals
var usedNumber = number
var counter = 0
while (usedNumber >= 1000 && number >= minForAbbrevation) {

View file

@ -95,6 +95,7 @@
<color name="yellow_1">#794b00</color>
<color name="orange_1">#7f3300</color>
<color name="brand_0">#30283D</color>
<color name="maroon_0">#3D2828</color>
<color name="red_0">#3D2828</color>
<color name="blue_0">#28373D</color>
@ -103,6 +104,7 @@
<color name="yellow_0">#3D3528</color>
<color name="orange_0">#3D3028</color>
<color name="brand_00">#201C26</color>
<color name="maroon_00">#261C1C</color>
<color name="red_00">#261C1C</color>
<color name="blue_00">#191D21</color>
@ -115,6 +117,7 @@
<color name="xpColor">@color/yellow_100</color>
<color name="mpColor">@color/blue_100</color>
<color name="text_title">@color/gray_50</color>
<color name="text_primary">@color/gray_50</color>
<color name="text_secondary">@color/gray_100</color>
<color name="text_ternary">@color/gray_200</color>

View file

@ -65,6 +65,10 @@
<item quantity="one">%d Reward</item>
<item quantity="other">%d Rewards</item>
</plurals>
<plurals name="flagged_count">
<item quantity="one">Flagged %d tim2</item>
<item quantity="other">Flagged %d times, hidden</item>
</plurals>
<string name="create_task_title">Create a Task</string>
<string name="complete_task_title">Complete a Task</string>
<string name="create_task">Create %s</string>

View file

@ -1,2 +1,2 @@
NAME=4.1
CODE=4891
CODE=4901