mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-26 16:22:39 +00:00
Improve Talkback for tiles
Changes made: - Shop items now read out name of item, price with currency, limited availability, items owned and locked state (previously just price) - In equipment, name of item or none will be read out in addition to slot (previously just slot) - In stable, hatchable pets will be read out as name of pet and "Hatch Pet" (previously unlabelled) - In task creation, the click listener for the difficulty has been moved to the surrounding column so icon and text are grouped (previously icon was read as unlabeled and text was not clickable) - In navigation drawer, the profile picture is read out as "Profile" (previously unlabelled) My Habitica User-ID: 2bcd10dc-0ea9-4d95-b7a6-f55fa07af537
This commit is contained in:
parent
ff568fc68c
commit
07450f43ff
9 changed files with 152 additions and 96 deletions
|
|
@ -33,7 +33,8 @@
|
||||||
android:id="@+id/avatarView"
|
android:id="@+id/avatarView"
|
||||||
android:layout_width="70dp"
|
android:layout_width="70dp"
|
||||||
android:layout_height="70dp"
|
android:layout_height="70dp"
|
||||||
android:layout_gravity="center" />
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/profile"/>
|
||||||
</com.habitrpg.android.habitica.ui.RoundedFrameLayout>
|
</com.habitrpg.android.habitica.ui.RoundedFrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
android:textColor="@color/text_quad"
|
android:textColor="@color/text_quad"
|
||||||
android:paddingStart="2dp"
|
android:paddingStart="2dp"
|
||||||
android:paddingEnd="2dp"
|
android:paddingEnd="2dp"
|
||||||
|
android:accessibilityTraversalAfter="@id/container"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -89,5 +90,6 @@
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_alignEnd="@id/container"
|
android:layout_alignEnd="@id/container"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
style="@style/CountLabel"/>
|
style="@style/CountLabel"/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ class PetDetailRecyclerAdapter :
|
||||||
|
|
||||||
binding.eggView.startAnimation(Animations.bobbingAnimation(4f))
|
binding.eggView.startAnimation(Animations.bobbingAnimation(4f))
|
||||||
binding.hatchingPotionView.startAnimation(Animations.bobbingAnimation(-4f))
|
binding.hatchingPotionView.startAnimation(Animations.bobbingAnimation(-4f))
|
||||||
|
|
||||||
|
binding.root.contentDescription = "${item.text}, ${itemView.context.getString(R.string.hatch_pet)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(p0: View?) {
|
override fun onClick(p0: View?) {
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ fun AvatarOverviewView(
|
||||||
userViewModel.updateUser("preferences.autoEquip", it)
|
userViewModel.updateUser("preferences.autoEquip", it)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
EquipmentOverviewView(user?.items?.gear?.equipped, battleGearTwoHanded, { type, equipped ->
|
EquipmentOverviewView(user?.items?.gear?.owned, user?.items?.gear?.equipped, battleGearTwoHanded, { type, equipped ->
|
||||||
onEquipmentTap(type, equipped, false)
|
onEquipmentTap(type, equipped, false)
|
||||||
})
|
})
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -362,7 +362,7 @@ fun AvatarOverviewView(
|
||||||
userViewModel.updateUser("preferences.costume", it)
|
userViewModel.updateUser("preferences.costume", it)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
EquipmentOverviewView(user?.items?.gear?.costume, costumeTwoHanded, { type, equipped ->
|
EquipmentOverviewView(user?.items?.gear?.owned, user?.items?.gear?.costume, costumeTwoHanded, { type, equipped ->
|
||||||
onEquipmentTap(type, equipped, true)
|
onEquipmentTap(type, equipped, true)
|
||||||
}, modifier = Modifier.alpha(if (user?.preferences?.costume == true) 1.0f else 0.5f))
|
}, modifier = Modifier.alpha(if (user?.preferences?.costume == true) 1.0f else 0.5f))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.databinding.RowShopitemBinding
|
import com.habitrpg.android.habitica.databinding.RowShopitemBinding
|
||||||
|
import com.habitrpg.android.habitica.extensions.getImpreciseRemainingString
|
||||||
|
import com.habitrpg.android.habitica.extensions.getRemainingString
|
||||||
|
import com.habitrpg.android.habitica.extensions.getShortRemainingString
|
||||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||||
|
|
@ -52,6 +55,8 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
this.item = item
|
this.item = item
|
||||||
binding.buyButton.visibility = View.VISIBLE
|
binding.buyButton.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
var contentDescription = item.text
|
||||||
|
|
||||||
binding.imageView.loadImage(item.imageName?.replace("_locked", ""))
|
binding.imageView.loadImage(item.imageName?.replace("_locked", ""))
|
||||||
|
|
||||||
binding.itemDetailIndicator.text = null
|
binding.itemDetailIndicator.text = null
|
||||||
|
|
@ -66,10 +71,12 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
}
|
}
|
||||||
binding.priceLabel.visibility = View.VISIBLE
|
binding.priceLabel.visibility = View.VISIBLE
|
||||||
binding.unlockLabel.visibility = View.GONE
|
binding.unlockLabel.visibility = View.GONE
|
||||||
|
contentDescription += ", ${item.value} ${binding.priceLabel.currencyContentDescription}"
|
||||||
} else {
|
} else {
|
||||||
binding.unlockLabel.text = lockedReason
|
binding.unlockLabel.text = lockedReason
|
||||||
binding.priceLabel.visibility = View.GONE
|
binding.priceLabel.visibility = View.GONE
|
||||||
binding.unlockLabel.visibility = View.VISIBLE
|
binding.unlockLabel.visibility = View.VISIBLE
|
||||||
|
contentDescription += ", $lockedReason"
|
||||||
}
|
}
|
||||||
val isLimited = item.isLimited || item.availableUntil != null
|
val isLimited = item.isLimited || item.availableUntil != null
|
||||||
if (numberOwned > 0) {
|
if (numberOwned > 0) {
|
||||||
|
|
@ -82,10 +89,12 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
binding.itemDetailIndicator.setTextColor(ContextCompat.getColor(context, R.color.text_quad))
|
binding.itemDetailIndicator.setTextColor(ContextCompat.getColor(context, R.color.text_quad))
|
||||||
}
|
}
|
||||||
binding.itemDetailIndicator.visibility = View.VISIBLE
|
binding.itemDetailIndicator.visibility = View.VISIBLE
|
||||||
|
contentDescription += ", ${context.getString(R.string.owned)}: $numberOwned"
|
||||||
} else if (item.locked) {
|
} else if (item.locked) {
|
||||||
binding.itemDetailIndicator.background =
|
binding.itemDetailIndicator.background =
|
||||||
AppCompatResources.getDrawable(context, if (isLimited) R.drawable.shop_locked_limited else R.drawable.shop_locked)
|
AppCompatResources.getDrawable(context, if (isLimited) R.drawable.shop_locked_limited else R.drawable.shop_locked)
|
||||||
binding.itemDetailIndicator.visibility = View.VISIBLE
|
binding.itemDetailIndicator.visibility = View.VISIBLE
|
||||||
|
contentDescription += ", ${context.getString(R.string.locked)}"
|
||||||
} else if (isLimited) {
|
} else if (isLimited) {
|
||||||
if (numberOwned == 0) {
|
if (numberOwned == 0) {
|
||||||
binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.shop_limited)
|
binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.shop_limited)
|
||||||
|
|
@ -93,6 +102,10 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.pill_bg_purple_300)
|
binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.pill_bg_purple_300)
|
||||||
}
|
}
|
||||||
binding.itemDetailIndicator.visibility = View.VISIBLE
|
binding.itemDetailIndicator.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
item.availableUntil?.let {
|
||||||
|
contentDescription += ", ${it.getImpreciseRemainingString(context.resources)}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val limitedLeft = item.limitedNumberLeft ?: limitedNumberLeft
|
val limitedLeft = item.limitedNumberLeft ?: limitedNumberLeft
|
||||||
|
|
@ -100,12 +113,14 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
binding.itemDetailIndicator.background =
|
binding.itemDetailIndicator.background =
|
||||||
AppCompatResources.getDrawable(context, R.drawable.item_indicator_subscribe)
|
AppCompatResources.getDrawable(context, R.drawable.item_indicator_subscribe)
|
||||||
binding.itemDetailIndicator.visibility = View.VISIBLE
|
binding.itemDetailIndicator.visibility = View.VISIBLE
|
||||||
|
contentDescription += ", ${context.getString(R.string.locked)}"
|
||||||
} else if (item.key == "gem") {
|
} else if (item.key == "gem") {
|
||||||
binding.itemDetailIndicator.background =
|
binding.itemDetailIndicator.background =
|
||||||
AppCompatResources.getDrawable(context, R.drawable.pill_bg_green)
|
AppCompatResources.getDrawable(context, R.drawable.pill_bg_green)
|
||||||
binding.itemDetailIndicator.text = "$limitedLeft"
|
binding.itemDetailIndicator.text = "$limitedLeft"
|
||||||
binding.itemDetailIndicator.setTextColor(ContextCompat.getColor(context, R.color.white))
|
binding.itemDetailIndicator.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||||
binding.itemDetailIndicator.visibility = View.VISIBLE
|
binding.itemDetailIndicator.visibility = View.VISIBLE
|
||||||
|
contentDescription += ", ${context.getString(R.string.gems_left_nomax, limitedLeft)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding.itemDetailIndicator.visibility == View.VISIBLE) {
|
if (binding.itemDetailIndicator.visibility == View.VISIBLE) {
|
||||||
|
|
@ -120,6 +135,8 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.priceLabel.isLocked = item.locked || (!canBuy && item.currency == "gold")
|
binding.priceLabel.isLocked = item.locked || (!canBuy && item.currency == "gold")
|
||||||
|
|
||||||
|
binding.container.contentDescription = contentDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(view: View) {
|
override fun onClick(view: View) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.res.colorResource
|
import androidx.compose.ui.res.colorResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.TextUnit
|
import androidx.compose.ui.unit.TextUnit
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -58,7 +61,16 @@ fun CurrencyText(
|
||||||
} else {
|
} else {
|
||||||
value.toFloat()
|
value.toFloat()
|
||||||
}
|
}
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
|
val currencyName = when (currency) {
|
||||||
|
"gold" -> stringResource(R.string.gold_plural)
|
||||||
|
"gems" -> stringResource(R.string.gems)
|
||||||
|
"hourglasses" -> stringResource(R.string.mystic_hourglasses)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val amount = NumberAbbreviator.abbreviate(null, animatedValue, decimals, minForAbbreviation)
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier.semantics(mergeDescendants = true) {
|
||||||
|
contentDescription = "$amount $currencyName"
|
||||||
|
}) {
|
||||||
when (currency) {
|
when (currency) {
|
||||||
"gold" -> HabiticaIconsHelper.imageOfGold()
|
"gold" -> HabiticaIconsHelper.imageOfGold()
|
||||||
"gems" -> HabiticaIconsHelper.imageOfGem()
|
"gems" -> HabiticaIconsHelper.imageOfGem()
|
||||||
|
|
@ -66,14 +78,14 @@ fun CurrencyText(
|
||||||
else -> null
|
else -> null
|
||||||
}?.asImageBitmap()?.let { Image(it, null, Modifier.padding(end = 5.dp)) }
|
}?.asImageBitmap()?.let { Image(it, null, Modifier.padding(end = 5.dp)) }
|
||||||
Text(
|
Text(
|
||||||
NumberAbbreviator.abbreviate(null, animatedValue, decimals, minForAbbreviation),
|
text = amount,
|
||||||
color =
|
color =
|
||||||
when (currency) {
|
when (currency) {
|
||||||
"gold" -> colorResource(R.color.text_gold)
|
"gold" -> colorResource(R.color.text_gold)
|
||||||
"gems" -> colorResource(R.color.text_green)
|
"gems" -> colorResource(R.color.text_green)
|
||||||
"hourglasses" -> colorResource(R.color.text_brand)
|
"hourglasses" -> colorResource(R.color.text_brand)
|
||||||
else -> colorResource(R.color.text_primary)
|
else -> colorResource(R.color.text_primary)
|
||||||
},
|
},
|
||||||
fontSize = fontSize,
|
fontSize = fontSize,
|
||||||
fontWeight = FontWeight.SemiBold
|
fontWeight = FontWeight.SemiBold
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ class CurrencyView : androidx.appcompat.widget.AppCompatTextView {
|
||||||
configureCurrency()
|
configureCurrency()
|
||||||
updateVisibility()
|
updateVisibility()
|
||||||
}
|
}
|
||||||
private var currencyContentDescription: String? = null
|
var currencyContentDescription: String? = null
|
||||||
|
private set
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
val attributes =
|
val attributes =
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,15 @@ import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.res.colorResource
|
import androidx.compose.ui.res.colorResource
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
|
import androidx.compose.ui.semantics.isTraversalGroup
|
||||||
|
import androidx.compose.ui.semantics.semantics
|
||||||
|
import androidx.compose.ui.semantics.traversalIndex
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
|
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||||
import com.habitrpg.android.habitica.models.user.Outfit
|
import com.habitrpg.android.habitica.models.user.Outfit
|
||||||
import com.habitrpg.android.habitica.models.user.Preferences
|
import com.habitrpg.android.habitica.models.user.Preferences
|
||||||
import com.habitrpg.android.habitica.ui.theme.colors
|
import com.habitrpg.android.habitica.ui.theme.colors
|
||||||
|
|
@ -31,32 +36,36 @@ import com.habitrpg.android.habitica.ui.theme.pixelArtBackground
|
||||||
import com.habitrpg.android.habitica.ui.views.PixelArtView
|
import com.habitrpg.android.habitica.ui.views.PixelArtView
|
||||||
import com.habitrpg.common.habitica.theme.HabiticaTheme
|
import com.habitrpg.common.habitica.theme.HabiticaTheme
|
||||||
import com.habitrpg.common.habitica.theme.caption2
|
import com.habitrpg.common.habitica.theme.caption2
|
||||||
|
import io.realm.RealmList
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun OverviewItem(
|
fun OverviewItem(
|
||||||
text: String,
|
text: String,
|
||||||
iconName: String?,
|
iconName: String?,
|
||||||
|
itemName: String = "",
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
isTwoHanded: Boolean = false
|
isTwoHanded: Boolean = false
|
||||||
) {
|
) {
|
||||||
val hasIcon =
|
val hasIcon =
|
||||||
isTwoHanded || (
|
isTwoHanded || (
|
||||||
iconName?.isNotBlank() == true && iconName != "shirt_" &&
|
iconName?.isNotBlank() == true && iconName != "shirt_" &&
|
||||||
!iconName.endsWith(
|
!iconName.endsWith(
|
||||||
"_none"
|
"_none"
|
||||||
) && !iconName.endsWith("_base_0") && !iconName.endsWith("_")
|
) && !iconName.endsWith("_base_0") && !iconName.endsWith("_")
|
||||||
)
|
)
|
||||||
|
val description = if (hasIcon) itemName else stringResource(R.string.none)
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
.width(76.dp)
|
.width(76.dp)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.size(76.dp)
|
.size(76.dp)
|
||||||
.clip(MaterialTheme.shapes.small)
|
.clip(MaterialTheme.shapes.small)
|
||||||
.background(HabiticaTheme.colors.pixelArtBackground(hasIcon)),
|
.background(HabiticaTheme.colors.pixelArtBackground(hasIcon))
|
||||||
|
.semantics { contentDescription = description },
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
if (isTwoHanded) {
|
if (isTwoHanded) {
|
||||||
|
|
@ -65,8 +74,8 @@ fun OverviewItem(
|
||||||
PixelArtView(
|
PixelArtView(
|
||||||
imageName = iconName,
|
imageName = iconName,
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.size(76.dp)
|
.size(76.dp)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Image(painterResource(R.drawable.empty_slot), null)
|
Image(painterResource(R.drawable.empty_slot), null)
|
||||||
|
|
@ -77,13 +86,15 @@ fun OverviewItem(
|
||||||
style = HabiticaTheme.typography.caption2,
|
style = HabiticaTheme.typography.caption2,
|
||||||
color = colorResource(R.color.text_secondary),
|
color = colorResource(R.color.text_secondary),
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
modifier = Modifier.padding(top = 4.dp)
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun EquipmentOverviewView(
|
fun EquipmentOverviewView(
|
||||||
|
owned: RealmList<Equipment>?,
|
||||||
outfit: Outfit?,
|
outfit: Outfit?,
|
||||||
isUsingTwohanded: Boolean,
|
isUsingTwohanded: Boolean,
|
||||||
onEquipmentTap: (String, String?) -> Unit,
|
onEquipmentTap: (String, String?) -> Unit,
|
||||||
|
|
@ -92,79 +103,87 @@ fun EquipmentOverviewView(
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(18.dp),
|
verticalArrangement = Arrangement.spacedBy(18.dp),
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MaterialTheme.shapes.medium)
|
||||||
.background(colorResource(R.color.equipment_column_background))
|
.background(colorResource(R.color.equipment_column_background))
|
||||||
.padding(12.dp)
|
.padding(12.dp)
|
||||||
) {
|
) {
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_weapon),
|
stringResource(R.string.outfit_weapon),
|
||||||
outfit?.weapon.let { "shop_$it" },
|
outfit?.weapon.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.weapon }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("weapon", outfit?.weapon)
|
onEquipmentTap("weapon", outfit?.weapon)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_shield),
|
stringResource(R.string.outfit_shield),
|
||||||
outfit?.shield.let { "shop_$it" },
|
outfit?.shield.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.shield }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("shield", outfit?.shield)
|
onEquipmentTap("shield", outfit?.shield)
|
||||||
},
|
},
|
||||||
isUsingTwohanded
|
isUsingTwohanded
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_head),
|
stringResource(R.string.outfit_head),
|
||||||
outfit?.head.let { "shop_$it" },
|
outfit?.head.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.head }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("head", outfit?.head)
|
onEquipmentTap("head", outfit?.head)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_armor),
|
stringResource(R.string.outfit_armor),
|
||||||
outfit?.armor.let { "shop_$it" },
|
outfit?.armor.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.armor }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("armor", outfit?.armor)
|
onEquipmentTap("armor", outfit?.armor)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_headAccessory),
|
stringResource(R.string.outfit_headAccessory),
|
||||||
outfit?.headAccessory.let { "shop_$it" },
|
outfit?.headAccessory.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.headAccessory }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("headAccessory", outfit?.headAccessory)
|
onEquipmentTap("headAccessory", outfit?.headAccessory)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_body),
|
stringResource(R.string.outfit_body),
|
||||||
outfit?.body.let { "shop_$it" },
|
outfit?.body.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.body }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("body", outfit?.body)
|
onEquipmentTap("body", outfit?.body)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_back),
|
stringResource(R.string.outfit_back),
|
||||||
outfit?.back.let { "shop_$it" },
|
outfit?.back.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.back }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("back", outfit?.back)
|
onEquipmentTap("back", outfit?.back)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.outfit_eyewear),
|
stringResource(R.string.outfit_eyewear),
|
||||||
outfit?.eyeWear.let { "shop_$it" },
|
outfit?.eyeWear.let { "shop_$it" },
|
||||||
|
itemName = owned?.firstOrNull { it.key == outfit?.eyeWear }?.text ?: "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onEquipmentTap("eyewear", outfit?.eyeWear)
|
onEquipmentTap("eyewear", outfit?.eyeWear)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,44 +200,44 @@ fun AvatarCustomizationOverviewView(
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(18.dp),
|
verticalArrangement = Arrangement.spacedBy(18.dp),
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MaterialTheme.shapes.medium)
|
||||||
.background(colorResource(R.color.equipment_column_background))
|
.background(colorResource(R.color.equipment_column_background))
|
||||||
.padding(12.dp)
|
.padding(12.dp)
|
||||||
) {
|
) {
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_shirt),
|
stringResource(R.string.avatar_shirt),
|
||||||
preferences?.shirt.let { "icon_${preferences?.size}_shirt_$it" },
|
preferences?.shirt.let { "icon_${preferences?.size}_shirt_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("shirt", null)
|
onCustomizationTap("shirt", null)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_skin),
|
stringResource(R.string.avatar_skin),
|
||||||
preferences?.skin.let { "icon_skin_$it" },
|
preferences?.skin.let { "icon_skin_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("skin", null)
|
onCustomizationTap("skin", null)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_hair_color),
|
stringResource(R.string.avatar_hair_color),
|
||||||
if (preferences?.hair?.color != null && preferences.hair?.color != "") "icon_hair_bangs_1_" + preferences.hair?.color else "",
|
if (preferences?.hair?.color != null && preferences.hair?.color != "") "icon_hair_bangs_1_" + preferences.hair?.color else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "color")
|
onCustomizationTap("hair", "color")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_hair_bangs),
|
stringResource(R.string.avatar_hair_bangs),
|
||||||
if (preferences?.hair?.bangs != null && preferences.hair?.bangs != 0) "icon_hair_bangs_" + preferences.hair?.bangs + "_" + preferences.hair?.color else "",
|
if (preferences?.hair?.bangs != null && preferences.hair?.bangs != 0) "icon_hair_bangs_" + preferences.hair?.bangs + "_" + preferences.hair?.color else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "bangs")
|
onCustomizationTap("hair", "bangs")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
|
|
@ -226,33 +245,33 @@ fun AvatarCustomizationOverviewView(
|
||||||
stringResource(R.string.avatar_style),
|
stringResource(R.string.avatar_style),
|
||||||
if (preferences?.hair?.base != null && preferences.hair?.base != 0) "icon_hair_base_" + preferences.hair?.base + "_" + preferences.hair?.color else "",
|
if (preferences?.hair?.base != null && preferences.hair?.base != 0) "icon_hair_base_" + preferences.hair?.base + "_" + preferences.hair?.color else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "base")
|
onCustomizationTap("hair", "base")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_mustache),
|
stringResource(R.string.avatar_mustache),
|
||||||
if (preferences?.hair?.mustache != null && preferences.hair?.mustache != 0) "icon_hair_mustache_" + preferences.hair?.mustache + "_" + preferences.hair?.color else "",
|
if (preferences?.hair?.mustache != null && preferences.hair?.mustache != 0) "icon_hair_mustache_" + preferences.hair?.mustache + "_" + preferences.hair?.color else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "mustache")
|
onCustomizationTap("hair", "mustache")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_beard),
|
stringResource(R.string.avatar_beard),
|
||||||
if (preferences?.hair?.beard != null && preferences.hair?.beard != 0) "icon_hair_beard_" + preferences.hair?.beard + "_" + preferences.hair?.color else "",
|
if (preferences?.hair?.beard != null && preferences.hair?.beard != 0) "icon_hair_beard_" + preferences.hair?.beard + "_" + preferences.hair?.color else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "beard")
|
onCustomizationTap("hair", "beard")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_flower),
|
stringResource(R.string.avatar_flower),
|
||||||
if (preferences?.hair?.flower != null && preferences.hair?.flower != 0) "icon_hair_flower_" + preferences.hair?.flower else "",
|
if (preferences?.hair?.flower != null && preferences.hair?.flower != 0) "icon_hair_flower_" + preferences.hair?.flower else "",
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("hair", "flower")
|
onCustomizationTap("hair", "flower")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
|
|
@ -260,33 +279,33 @@ fun AvatarCustomizationOverviewView(
|
||||||
stringResource(R.string.avatar_wheelchair),
|
stringResource(R.string.avatar_wheelchair),
|
||||||
preferences?.chair?.let { if (it.startsWith("handleless")) "icon_chair_$it" else "icon_$it" },
|
preferences?.chair?.let { if (it.startsWith("handleless")) "icon_chair_$it" else "icon_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("chair", null)
|
onCustomizationTap("chair", null)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.avatar_background),
|
stringResource(R.string.avatar_background),
|
||||||
preferences?.background.let { "icon_background_$it" },
|
preferences?.background.let { "icon_background_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onCustomizationTap("background", null)
|
onCustomizationTap("background", null)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.animal_ears),
|
stringResource(R.string.animal_ears),
|
||||||
outfit?.headAccessory.let { "shop_$it" },
|
outfit?.headAccessory.let { "shop_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onAvatarEquipmentTap("headAccessory", "animal")
|
onAvatarEquipmentTap("headAccessory", "animal")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
OverviewItem(
|
OverviewItem(
|
||||||
stringResource(R.string.animal_tail),
|
stringResource(R.string.animal_tail),
|
||||||
outfit?.back.let { "shop_$it" },
|
outfit?.back.let { "shop_$it" },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
onAvatarEquipmentTap("back", "animal")
|
onAvatarEquipmentTap("back", "animal")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +323,7 @@ fun EquipmentOverviewItemPreview() {
|
||||||
OverviewItem("Off-Hand", null, isTwoHanded = true)
|
OverviewItem("Off-Hand", null, isTwoHanded = true)
|
||||||
OverviewItem("Armor", null)
|
OverviewItem("Armor", null)
|
||||||
}
|
}
|
||||||
EquipmentOverviewView(null, false, { _, _ -> })
|
EquipmentOverviewView(null, null, false, { _, _ -> })
|
||||||
AvatarCustomizationOverviewView(null, null, { _, _ -> }, { _, _ -> })
|
AvatarCustomizationOverviewView(null, null, { _, _ -> }, { _, _ -> })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.colorResource
|
import androidx.compose.ui.res.colorResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
|
import androidx.compose.ui.semantics.isTraversalGroup
|
||||||
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
|
@ -100,7 +103,7 @@ private fun TaskDifficultySelection(
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
modifier = modifier
|
modifier = modifier.clickable { onSelect(value) }
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
|
|
@ -114,7 +117,6 @@ private fun TaskDifficultySelection(
|
||||||
MaterialTheme.shapes.medium
|
MaterialTheme.shapes.medium
|
||||||
)
|
)
|
||||||
.clip(MaterialTheme.shapes.medium)
|
.clip(MaterialTheme.shapes.medium)
|
||||||
.clickable { onSelect(value) }
|
|
||||||
) {
|
) {
|
||||||
this@Column.AnimatedVisibility(
|
this@Column.AnimatedVisibility(
|
||||||
selected,
|
selected,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue