add sheet for mounts

This commit is contained in:
Phillip Thelen 2023-09-08 14:19:20 +02:00
parent a60d895a5d
commit a4bf3dc51c
25 changed files with 441 additions and 113 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="24dp" android:height="24dp">
<shape>
<solid android:color="@color/offset_background"/>
<corners android:radius="20dip"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>
</item>
<item android:width="10dp" android:height="12dp" android:gravity="center">
<bitmap android:src="@drawable/icon_lock" android:tintMode="src_atop" android:tint="@color/text_quad">
</bitmap>
</item>
</layer-list>

View file

@ -85,6 +85,7 @@
android:textStyle="bold"
android:textSize="28sp"
android:gravity="center"
android:alpha="0"
android:textColor="@color/text_primary"/>
<TextView
android:id="@+id/subtitle_view"
@ -98,6 +99,7 @@
android:textSize="20sp"
android:letterSpacing="0.04"
android:lineSpacingExtra="2dp"
android:alpha="0"
/>
</LinearLayout>
<Space
@ -160,38 +162,52 @@
android:layout_marginHorizontal="24dp"
app:currency="gold" />
<FrameLayout
<LinearLayout
android:id="@+id/open_armoire_subscriber_wrapper"
android:layout_width="match_parent"
android:layout_height="65dp"
android:paddingStart="24dp"
android:paddingEnd="18dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="4dp">
<TextView
android:id="@+id/open_armoire_subscriber_button"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="@string/subscriber_button_armoire"
android:textStyle="bold"
android:background="@drawable/subscriber_benefit_button_bg"
android:gravity="center"
android:textSize="16sp"
android:backgroundTint="@null"
android:textColor="@color/green_1"
android:layout_marginEnd="6dp"
android:layout_marginTop="5dp"
android:padding="0dp"/>
android:layout_height="65dp"
android:paddingStart="24dp"
android:paddingEnd="18dp">
<TextView
android:id="@+id/open_armoire_subscriber_button"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="@string/subscriber_button_armoire"
android:textStyle="bold"
android:background="@drawable/subscriber_benefit_button_bg"
android:gravity="center"
android:textSize="16sp"
android:backgroundTint="@null"
android:textColor="@color/green_1"
android:layout_marginEnd="6dp"
android:layout_marginTop="5dp"
android:padding="0dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/sub_perk_bg"
android:textColor="@color/green_500"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
style="@style/Caption2"
android:layout_gravity="top|end"
android:text="@string/sub_perk"/>
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sub_perk_bg"
android:textColor="@color/green_500"
android:paddingHorizontal="6dp"
android:paddingVertical="4dp"
style="@style/Caption2"
android:layout_gravity="top|end"
android:text="@string/sub_perk"/>
</FrameLayout>
android:text="@string/subscription_benefit_armoire_sub"
android:textColor="@color/white"
style="@style/Body2"
android:gravity="center"
android:paddingHorizontal="48dp"
android:layout_marginTop="6dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/unsubbed_wrapper"

View file

@ -103,7 +103,8 @@
tools:text="1"
android:inputType="number"
android:background="@color/transparent"
android:textColor="@color/text_secondary"/>
android:textColor="@color/text_secondary"
android:paddingVertical="2dp"/>
<TextView
android:id="@+id/repeats_every_title"
@ -128,19 +129,21 @@
android:orientation="horizontal">
<TextView
android:id="@+id/monthly_repeat_days"
style="@style/TaskFormToggle"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="28dp"
android:layout_height="48dp"
android:gravity="center"
android:background="@drawable/layout_rounded_bg_content"
android:text="@string/repeatables_frequency_day_of_month"
android:layout_marginEnd="@dimen/spacing_medium"/>
<TextView
android:id="@+id/monthly_repeat_weeks"
style="@style/TaskFormToggle"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="28dp"
android:layout_height="48dp"
android:text="@string/repeatables_frequency_day_of_week"
android:gravity="center"
android:background="@drawable/layout_rounded_bg_content"
android:layout_marginStart="@dimen/spacing_medium"/>
</LinearLayout>
<TextView
@ -150,4 +153,4 @@
android:textColor="?textColorTintedSecondary"
android:textSize="12sp"
android:layout_marginTop="@dimen/spacing_medium"/>
</merge>
</merge>

View file

@ -1457,6 +1457,7 @@
<string name="preference_push_invited_to_group_plan">Invited to Group Plan</string>
<string name="preference_push_joined_group_plan_mention">\@Mentions in Group Plans</string>
<string name="subscribe_incentive_button_faint">Subscribe to hold on with 1HP!</string>
<string name="subscription_benefit_armoire_sub">Your subscription gives you an extra chance at the Armoire!</string>
<plurals name="you_x_others">

View file

@ -36,6 +36,7 @@ import com.habitrpg.common.habitica.helpers.launchCatching
import com.plattysoft.leonids.ParticleSystem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import java.util.Locale
@ -173,8 +174,36 @@ class ArmoireActivity : BaseActivity() {
}
private fun giveUserArmoire(): Boolean {
binding.iconWrapper.post {
binding.iconView.bitmap = null
Animations.circularHide(binding.iconWrapper)
}
binding.titleView.animate().apply {
alpha(0f)
duration = 300
startDelay = 0
start()
}
binding.subtitleView.animate().apply {
alpha(0f)
duration = 300
startDelay = 0
start()
}
binding.goldView.animate().apply {
alpha(0f)
start()
}
val user = userViewModel.user.value ?: return true
val currentGold = user.stats?.gp ?: return true
if (binding.adButton.visibility == View.VISIBLE) {
binding.adButton.state = AdButton.State.UNAVAILABLE
binding.adButton.visibility = View.INVISIBLE
} else if (binding.openArmoireSubscriberWrapper.visibility == View.VISIBLE) {
binding.openArmoireSubscriberWrapper.visibility = View.INVISIBLE
}
lifecycleScope.launch(ExceptionHandler.coroutine()) {
userRepository.updateUser("stats.gp", currentGold + 100)
val buyResponse =
@ -185,27 +214,25 @@ class ArmoireActivity : BaseActivity() {
buyResponse.armoire["dropText"] ?: "",
buyResponse.armoire["value"] ?: ""
)
if (binding.adButton.visibility == View.VISIBLE) {
binding.adButton.state = AdButton.State.UNAVAILABLE
binding.adButton.visibility = View.INVISIBLE
} else if (binding.openArmoireSubscriberWrapper.visibility == View.VISIBLE) {
binding.openArmoireSubscriberWrapper.visibility = View.INVISIBLE
}
hasAnimatedChanges = false
gold = null
startAnimation(false)
}
return false
}
override fun onResume() {
super.onResume()
startAnimation()
lifecycleScope.launchCatching {
delay(500L)
startAnimation(true)
}
}
private fun startAnimation() {
private fun startAnimation(decreaseGold: Boolean) {
val gold = gold?.toInt()
if (hasAnimatedChanges) return
if (gold != null) {
if (gold != null && decreaseGold) {
/**
* We are adding 100 as the gold is already "deducted" before the animation starts,
* and animating to show the current user's gold amount.

View file

@ -291,7 +291,7 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
binding?.questParticipationView?.setTextColor(
ContextCompat.getColor(
it,
R.color.text_quad
R.color.text_ternary
)
)
}

View file

@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.ui.viewHolders
import android.app.Activity
import android.content.res.Resources
import android.graphics.drawable.BitmapDrawable
import android.view.View
@ -11,7 +12,11 @@ import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.models.inventory.Mount
import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu
import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem
import com.habitrpg.android.habitica.ui.views.showAsBottomSheet
import com.habitrpg.android.habitica.ui.views.stable.MountBottomSheet
import com.habitrpg.android.habitica.ui.views.stable.PetBottomSheet
import com.habitrpg.common.habitica.extensions.DataBindingUtils
import dagger.hilt.android.internal.managers.ViewComponentManager
class MountViewHolder(parent: ViewGroup, private val onEquip: ((String) -> Unit)?) : androidx.recyclerview.widget.RecyclerView.ViewHolder(parent.inflate(R.layout.mount_overview_item)), View.OnClickListener {
private var binding: MountOverviewItemBinding = MountOverviewItemBinding.bind(itemView)
@ -51,16 +56,20 @@ class MountViewHolder(parent: ViewGroup, private val onEquip: ((String) -> Unit)
if (!owned) {
return
}
val menu = BottomSheetMenu(itemView.context)
menu.setTitle(animal?.text)
menu.setImage("stable_Mount_Icon_" + animal?.animal + "-" + animal?.color)
val hasCurrentMount = currentMount.equals(animal?.key)
val labelId = if (hasCurrentMount) R.string.unequip else R.string.equip
menu.addMenuItem(BottomSheetMenuItem(resources.getString(labelId)))
menu.setSelectionRunnable {
animal?.let { onEquip?.invoke(it.key ?: "") }
val context = itemView.context
animal?.let { pet ->
(if (context is ViewComponentManager.FragmentContextWrapper) {
context.baseContext
} else {
context
}as Activity).showAsBottomSheet {
MountBottomSheet(
pet,
currentMount.equals(animal?.key),
onEquip,
it
)
}
}
menu.show()
}
}

View file

@ -72,8 +72,7 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
binding.itemDetailIndicator.background =
AppCompatResources.getDrawable(context, R.drawable.pill_bg_gray)
binding.itemDetailIndicator.visibility = View.VISIBLE
}
if (item.locked) {
} else if (item.locked) {
binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.shop_locked)
binding.itemDetailIndicator.visibility = View.VISIBLE
} else if (isLimited) {

View file

@ -0,0 +1,73 @@
package com.habitrpg.android.habitica.ui.views
import android.graphics.Bitmap
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.ImageShader
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import com.habitrpg.android.habitica.R
import java.util.Calendar
@Composable
private fun getBackgroundPainter(): ImageBitmap {
val calendar = Calendar.getInstance()
val month = calendar.get(Calendar.MONTH)
return ImageBitmap.imageResource(
when (month) {
Calendar.JANUARY -> R.drawable.stable_tile_janurary
Calendar.FEBRUARY -> R.drawable.stable_tile_february
Calendar.MARCH -> R.drawable.stable_tile_march
Calendar.APRIL -> R.drawable.stable_tile_april
Calendar.MAY -> R.drawable.stable_tile_may
Calendar.JUNE -> R.drawable.stable_tile_june
Calendar.JULY -> R.drawable.stable_tile_july
Calendar.AUGUST -> R.drawable.stable_tile_august
Calendar.SEPTEMBER -> R.drawable.stable_tile_september
Calendar.OCTOBER -> R.drawable.stable_tile_october
Calendar.NOVEMBER -> R.drawable.stable_tile_november
Calendar.DECEMBER -> R.drawable.stable_tile_december
else -> R.drawable.stable_tile_may
}
)
}
@Composable
fun BackgroundScene() {
val image = getBackgroundPainter()
Canvas(
modifier = Modifier
.height(124.dp)
.fillMaxWidth()
.zIndex(1f), onDraw = {
val bitmap = Bitmap.createScaledBitmap(
image.asAndroidBitmap(),
image.width.dp.roundToPx(),
124.dp.roundToPx(),
false
)
val paint = Paint().asFrameworkPaint().apply {
isAntiAlias = true
shader = ImageShader(
bitmap.asImageBitmap(),
TileMode.Repeated,
TileMode.Repeated
)
}
drawIntoCanvas {
it.nativeCanvas.drawPaint(paint)
}
paint.reset()
})
}

View file

@ -31,8 +31,8 @@ fun HabiticaButton(
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.clickable { onClick() }
.background(background, HabiticaTheme.shapes.medium)
.clickable { onClick() }
.fillMaxWidth()
.padding(contentPadding)
) {

View file

@ -0,0 +1,179 @@
package com.habitrpg.android.habitica.ui.views.stable
import com.habitrpg.android.habitica.models.inventory.Animal
import com.habitrpg.android.habitica.models.inventory.Mount
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.StartOffset
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
import com.habitrpg.android.habitica.ui.views.BackgroundScene
import com.habitrpg.android.habitica.ui.views.HabiticaButton
import java.util.Calendar
import kotlin.math.sin
@Composable
private fun getBackgroundPainter(): ImageBitmap {
val calendar = Calendar.getInstance()
val month = calendar.get(Calendar.MONTH)
return ImageBitmap.imageResource(
when (month) {
Calendar.JANUARY -> R.drawable.stable_tile_janurary
Calendar.FEBRUARY -> R.drawable.stable_tile_february
Calendar.MARCH -> R.drawable.stable_tile_march
Calendar.APRIL -> R.drawable.stable_tile_april
Calendar.MAY -> R.drawable.stable_tile_may
Calendar.JUNE -> R.drawable.stable_tile_june
Calendar.JULY -> R.drawable.stable_tile_july
Calendar.AUGUST -> R.drawable.stable_tile_august
Calendar.SEPTEMBER -> R.drawable.stable_tile_september
Calendar.OCTOBER -> R.drawable.stable_tile_october
Calendar.NOVEMBER -> R.drawable.stable_tile_november
Calendar.DECEMBER -> R.drawable.stable_tile_december
else -> R.drawable.stable_tile_may
}
)
}
@Composable
fun MountBottomSheet(
mount: Mount,
isCurrentMount: Boolean,
onEquip: ((String) -> Unit)?,
onDismiss: () -> Unit,
modifier: Modifier = Modifier
) {
val infiniteTransition = rememberInfiniteTransition()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.padding(horizontal = 22.dp)
) {
Text(
mount.text ?: "",
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
color = HabiticaTheme.colors.textTertiary
)
Box(
modifier = Modifier
.padding(top = 9.dp, bottom = 16.dp)
.fillMaxWidth()
.height(124.dp)
.clip(HabiticaTheme.shapes.medium)
) {
BackgroundScene()
val regularPosition = 33f
val highJump = 22f
val lowJump = 30f
val position by if (isAnimalFlying(mount)) {
infiniteTransition.animateFloat(
initialValue = 24f,
targetValue = 16f,
animationSpec = infiniteRepeatable(
tween(
2500,
easing = CubicBezierEasing(0.3f, 0.0f, 0.2f, 1.0f)
), RepeatMode.Reverse
),
label = "animalPosition"
)
} else {
infiniteTransition.animateFloat(
initialValue = regularPosition,
targetValue = highJump,
animationSpec = infiniteRepeatable(animation = keyframes {
durationMillis = 6000
regularPosition at 0 with LinearOutSlowInEasing
highJump at 150 with LinearOutSlowInEasing
regularPosition at 300 with FastOutSlowInEasing
regularPosition at 1800 with FastOutSlowInEasing
lowJump at 1850 with LinearOutSlowInEasing
regularPosition at 1900 with LinearOutSlowInEasing
regularPosition at 2100 with FastOutSlowInEasing
lowJump at 2200 with LinearOutSlowInEasing
regularPosition at 2350 with LinearOutSlowInEasing
regularPosition at 6000
}, RepeatMode.Restart, StartOffset(1500)), label = "animalPosition"
)
}
MountView(mount, modifier = Modifier
.offset(0.dp, position.dp)
.size(68.dp)
.align(Alignment.TopCenter)
.zIndex(2f)
)
}
HabiticaButton(
background = HabiticaTheme.colors.tintedUiSub,
color = Color.White,
contentPadding = PaddingValues(12.dp),
onClick = {
onEquip?.invoke(mount.key)
onDismiss()
}) {
if (isCurrentMount) {
Text(stringResource(id = R.string.unequip))
} else {
Text(stringResource(id = R.string.equip))
}
}
}
}
fun isAnimalFlying(animal: Animal): Boolean {
if (listOf(
"FlyingPig",
"Bee"
).contains(animal.animal)
) return true
return listOf(
"Ghost",
"Cupid",
"Fairy",
"SolarSystem",
"Vampire"
).contains(animal.color)
}

View file

@ -0,0 +1,48 @@
package com.habitrpg.android.habitica.ui.views.stable
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.viewinterop.AndroidView
import com.habitrpg.android.habitica.models.inventory.Mount
import com.habitrpg.common.habitica.extensions.loadImage
import com.habitrpg.common.habitica.views.PixelArtView
class MountView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : FrameLayout(context, attrs) {
private val bodyView: PixelArtView = PixelArtView(context)
private val headView: PixelArtView = PixelArtView(context)
fun setMount(key: String) {
bodyView.loadImage("Mount_Body_$key")
headView.loadImage("Mount_Head_$key")
}
init {
addView(bodyView)
addView(headView)
}
}
@Composable
fun MountView(mount: Mount, modifier: Modifier = Modifier) {
MountView(mount.key, modifier)
}
@Composable
fun MountView(mountKey: String, modifier: Modifier = Modifier) {
AndroidView(
modifier = modifier,
factory = { context ->
MountView(context)
},
update = { view ->
view.setMount(mountKey)
}
)
}

View file

@ -55,6 +55,7 @@ import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.stringResource
@ -67,38 +68,16 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.models.inventory.Food
import com.habitrpg.android.habitica.models.inventory.Pet
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
import com.habitrpg.android.habitica.ui.views.BackgroundScene
import com.habitrpg.android.habitica.ui.views.HabiticaButton
import com.habitrpg.android.habitica.ui.views.PixelArtView
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.common.habitica.helpers.MainNavigationController
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.shared.habitica.models.responses.FeedResponse
import kotlinx.coroutines.delay
import java.util.Calendar
import kotlin.math.sin
@Composable
private fun getBackgroundPainter(): ImageBitmap {
val calendar = Calendar.getInstance()
val month = calendar.get(Calendar.MONTH)
return ImageBitmap.imageResource(
when (month) {
Calendar.JANUARY -> R.drawable.stable_tile_janurary
Calendar.FEBRUARY -> R.drawable.stable_tile_february
Calendar.MARCH -> R.drawable.stable_tile_march
Calendar.APRIL -> R.drawable.stable_tile_april
Calendar.MAY -> R.drawable.stable_tile_may
Calendar.JUNE -> R.drawable.stable_tile_june
Calendar.JULY -> R.drawable.stable_tile_july
Calendar.AUGUST -> R.drawable.stable_tile_august
Calendar.SEPTEMBER -> R.drawable.stable_tile_september
Calendar.OCTOBER -> R.drawable.stable_tile_october
Calendar.NOVEMBER -> R.drawable.stable_tile_november
Calendar.DECEMBER -> R.drawable.stable_tile_december
else -> R.drawable.stable_tile_may
}
)
}
@Composable
private fun getFoodPainter(petColor: String): ImageBitmap {
return ImageBitmap.imageResource(
@ -152,7 +131,6 @@ fun PetBottomSheet(
fontWeight = FontWeight.Medium,
color = HabiticaTheme.colors.textTertiary
)
val image = getBackgroundPainter()
Box(
modifier = Modifier
.padding(top = 9.dp, bottom = 16.dp)
@ -160,30 +138,7 @@ fun PetBottomSheet(
.height(124.dp)
.clip(HabiticaTheme.shapes.medium)
) {
Canvas(
modifier = Modifier
.height(124.dp)
.fillMaxWidth()
.zIndex(1f), onDraw = {
val bitmap = Bitmap.createScaledBitmap(
image.asAndroidBitmap(),
image.width.dp.roundToPx(),
124.dp.roundToPx(),
false
)
val paint = Paint().asFrameworkPaint().apply {
isAntiAlias = true
shader = ImageShader(
bitmap.asImageBitmap(),
TileMode.Repeated,
TileMode.Repeated
)
}
drawIntoCanvas {
it.nativeCanvas.drawPaint(paint)
}
paint.reset()
})
BackgroundScene()
this@Column.AnimatedVisibility(
visible = showFeedResponse, modifier = Modifier
@ -298,7 +253,7 @@ fun PetBottomSheet(
modifier = Modifier.padding(bottom = 16.dp)
) {
HabiticaButton(
colorResource(id = R.color.offset_background_30),
Color(LocalContext.current.getThemeColor(R.attr.colorTintedBackgroundOffset)),
HabiticaTheme.colors.textPrimary,
onClick = {
if (ownsSaddles) {
@ -324,7 +279,7 @@ fun PetBottomSheet(
}
}
HabiticaButton(
colorResource(id = R.color.offset_background_30),
Color(LocalContext.current.getThemeColor(R.attr.colorTintedBackgroundOffset)),
HabiticaTheme.colors.textPrimary,
onClick = {
coroutineScope.launchCatching {

View file

@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.views.tasks.form
import android.app.DatePickerDialog
import android.content.Context
import android.content.DialogInterface
import android.content.res.ColorStateList
import android.icu.text.MessageFormat
import android.os.Build
import android.text.TextUtils
@ -321,14 +322,14 @@ class TaskSchedulingControls @JvmOverloads constructor(
}
private fun styleButtonAsActive(button: TextView) {
button.setTextColor(context.getThemeColor(R.attr.colorTintedBackground))
button.background.mutate().setTint(tintColor)
button.setTextColor(context.getThemeColor(R.attr.tintedUiDetails))
button.backgroundTintList = ColorStateList.valueOf(context.getThemeColor(R.attr.tintedUiMain))
button.contentDescription = toContentDescription(button.text, true)
}
private fun styleButtonAsInactive(button: TextView) {
button.setTextColor(context.getThemeColor(R.attr.colorPrimaryDark))
button.background.mutate().setTint(context.getThemeColor(R.attr.colorTintedBackgroundOffset))
button.setTextColor(context.getThemeColor(R.attr.textColorTintedSecondary))
button.backgroundTintList = ColorStateList.valueOf(context.getThemeColor(R.attr.colorTintedBackgroundOffset))
button.contentDescription = toContentDescription(button.text, false)
}

View file

@ -153,6 +153,7 @@ object DataBindingUtils {
tempMap["shield_special_ks2019"] = "gif"
tempMap["weapon_special_ks2019"] = "gif"
tempMap["Pet-Gryphon-Gryphatrice"] = "gif"
tempMap["stable_Pet-Gryphon-Gryphatrice"] = "gif"
tempMap["Mount_Head_Gryphon-Gryphatrice"] = "gif"
tempMap["Mount_Body_Gryphon-Gryphatrice"] = "gif"
tempMap["background_clocktower"] = "gif"

View file

@ -61,11 +61,13 @@ object Animations {
anim.start()
}
fun circularHide(view: View) {
fun circularHide(view: View, duration: Long = 300) {
val cx = view.width / 2
val cy = view.height / 2
val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0f)
anim.duration = duration
anim.interpolator = AccelerateInterpolator()
anim.doOnEnd {
view.visibility = View.INVISIBLE
}

View file

@ -84,7 +84,7 @@ class ValueBar(context: Context, attrs: AttributeSet?) : FrameLayout(context, at
private fun updateBar() {
binding.progressBar.set(currentValue, maxValue)
binding.progressBar.pendingValue = pendingValue
setValueText(formatter.format(currentValue) + " / " + formatter.format(maxValue.toInt()) + " " + valueSuffix)
setValueText(formatter.format(currentValue) + " / " + formatter.format(maxValue.toInt()) + " " + (valueSuffix ?: ""))
}
init {

View file

@ -1,2 +1,2 @@
NAME=4.3
CODE=6471
CODE=6491