mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-17 19:42:04 +00:00
Skill dialog bottom sheet
Bottom sheet dialog for displaying skill information Includes a new composable view: SkillDialog
This commit is contained in:
parent
ef2229e438
commit
6913582b91
4 changed files with 282 additions and 13 deletions
|
|
@ -0,0 +1,74 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.skills
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.views.SkillDialog
|
||||
import com.habitrpg.common.habitica.extensions.asPainter
|
||||
import com.habitrpg.common.habitica.theme.HabiticaTheme
|
||||
|
||||
class SkillDialogBottomSheetFragment : BottomSheetDialogFragment() {
|
||||
|
||||
companion object {
|
||||
private const val ARG_SKILL_TITLE = "skill_title"
|
||||
private const val ARG_SKILL_DESCRIPTION = "skill_description"
|
||||
private const val ARG_SKILL_MP_COST = "skill_mp_cost"
|
||||
|
||||
fun newInstance(
|
||||
skillTitle: String,
|
||||
skillDescription: String,
|
||||
skillMpCost: String,
|
||||
skillPath: String,
|
||||
skillKey: String,
|
||||
resourceIcon: Drawable,
|
||||
onUseSkill: () -> Unit
|
||||
): SkillDialogBottomSheetFragment {
|
||||
return SkillDialogBottomSheetFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(ARG_SKILL_TITLE, skillTitle)
|
||||
putString(ARG_SKILL_DESCRIPTION, skillDescription)
|
||||
putString(ARG_SKILL_MP_COST, skillMpCost)
|
||||
}
|
||||
this.resourceIcon = resourceIcon
|
||||
this.skillKey = skillKey
|
||||
this.skillPath = skillPath
|
||||
this.onUseSkill = onUseSkill
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var onUseSkill: (() -> Unit)? = null
|
||||
private var resourceIcon: Drawable? = null
|
||||
var skillKey = ""
|
||||
var skillPath = ""
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View = ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
HabiticaTheme {
|
||||
SkillDialog(
|
||||
skillKey = skillKey,
|
||||
skillPath = skillPath,
|
||||
resourceIconPainter = resourceIcon?.asPainter() ?: painterResource(R.drawable.empty_slot),
|
||||
title = requireArguments().getString(ARG_SKILL_TITLE) ?: "",
|
||||
description = requireArguments().getString(ARG_SKILL_DESCRIPTION) ?: "",
|
||||
mpCost = requireArguments().getString(ARG_SKILL_MP_COST) ?: "",
|
||||
onUseSkill = {
|
||||
onUseSkill?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.fragments.skills
|
|||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
|
@ -31,6 +32,9 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.views.PixelArtView
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SkillsFragment : BaseMainFragment<FragmentRecyclerviewBinding>() {
|
||||
|
|
@ -99,21 +103,38 @@ class SkillsFragment : BaseMainFragment<FragmentRecyclerviewBinding>() {
|
|||
}
|
||||
|
||||
private fun onSkillSelected(skill: Skill) {
|
||||
when {
|
||||
"special" == skill.habitClass -> {
|
||||
selectedSkill = skill
|
||||
val intent = Intent(mainActivity, SkillMemberActivity::class.java)
|
||||
memberSelectionResult.launch(intent)
|
||||
}
|
||||
val context = context ?: return
|
||||
val resourceIconDrawable: Drawable = HabiticaIconsHelper.imageOfMagic().toDrawable(context.resources)
|
||||
val skillIdentifier = "shop_"
|
||||
|
||||
val bottomSheet = SkillDialogBottomSheetFragment.newInstance(
|
||||
skillTitle = skill.text,
|
||||
skillDescription = skill.notes ?: "",
|
||||
skillKey = skill.key,
|
||||
skillPath = skillIdentifier,
|
||||
skillMpCost = "${skill.mana?.toInt() ?: 0} MP",
|
||||
resourceIcon = resourceIconDrawable,
|
||||
onUseSkill = {
|
||||
when {
|
||||
"special" == skill.habitClass -> {
|
||||
selectedSkill = skill
|
||||
val intent = Intent(mainActivity, SkillMemberActivity::class.java)
|
||||
memberSelectionResult.launch(intent)
|
||||
}
|
||||
|
||||
skill.target == "task" -> {
|
||||
selectedSkill = skill
|
||||
val intent = Intent(mainActivity, SkillTasksActivity::class.java)
|
||||
taskSelectionResult.launch(intent)
|
||||
}
|
||||
|
||||
else -> useSkill(skill)
|
||||
}
|
||||
}
|
||||
)
|
||||
bottomSheet.show(childFragmentManager, "SkillDialogBottomSheet")
|
||||
|
||||
skill.target == "task" -> {
|
||||
selectedSkill = skill
|
||||
val intent = Intent(mainActivity, SkillTasksActivity::class.java)
|
||||
taskSelectionResult.launch(intent)
|
||||
}
|
||||
|
||||
else -> useSkill(skill)
|
||||
}
|
||||
}
|
||||
|
||||
private fun displaySkillResult(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
package com.habitrpg.android.habitica.ui.views
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.habitrpg.android.habitica.R
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.habitrpg.android.habitica.ui.theme.colors
|
||||
import com.habitrpg.common.habitica.theme.HabiticaTheme
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.habitrpg.android.habitica.ui.theme.pixelArtBackground
|
||||
|
||||
@Composable
|
||||
fun SkillDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
skillPath: String = "",
|
||||
skillKey: String = "",
|
||||
resourceIconPainter: Painter,
|
||||
title: String,
|
||||
description: String,
|
||||
mpCost: String,
|
||||
onUseSkill: () -> Unit,
|
||||
) {
|
||||
val colors = HabiticaTheme.colors
|
||||
Box(
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.background(colors.windowBackground, shape = RoundedCornerShape(18.dp))
|
||||
.padding(horizontal = 24.dp, vertical = 18.dp)
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.padding(bottom = 12.dp)
|
||||
.size(width = 38.dp, height = 6.dp)
|
||||
.clip(CircleShape)
|
||||
.background(colors.textSecondary)
|
||||
)
|
||||
|
||||
Box(
|
||||
Modifier
|
||||
.size(54.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(colors.pixelArtBackground(hasIcon = true)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
PixelArtView (
|
||||
imageName = skillPath + skillKey,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(16.dp))
|
||||
|
||||
Text(
|
||||
text = title,
|
||||
fontSize = 22.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = colors.textPrimary,
|
||||
modifier = Modifier.padding(top = 2.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = description,
|
||||
fontSize = 15.sp,
|
||||
color = colors.textSecondary,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(18.dp))
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.background(Color(0xFF393F68))
|
||||
.padding(horizontal = 20.dp, vertical = 8.dp)
|
||||
) {
|
||||
Icon(
|
||||
painter = resourceIconPainter,
|
||||
contentDescription = null,
|
||||
tint = Color(0xFF77C7F7),
|
||||
modifier = Modifier.size(22.dp)
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text(
|
||||
text = mpCost,
|
||||
color = Color.White,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 16.sp
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(28.dp))
|
||||
|
||||
Button(
|
||||
onClick = onUseSkill,
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color(0xFFA380FC),
|
||||
contentColor = Color.White
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(48.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
) {
|
||||
Text(
|
||||
text = "Use Skill",
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 17.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = 0xFF232136)
|
||||
@Composable
|
||||
fun PreviewSkillDialog() {
|
||||
SkillDialog(
|
||||
skillKey = "",
|
||||
skillPath = "",
|
||||
resourceIconPainter = painterResource(id = R.drawable.empty_slot),
|
||||
title = "Title Skill",
|
||||
description = "Skill Description",
|
||||
mpCost = "10 MP",
|
||||
onUseSkill = {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -2,7 +2,11 @@ package com.habitrpg.common.habitica.extensions
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
|
||||
|
|
@ -22,3 +26,9 @@ fun Drawable.setTintWith(
|
|||
DrawableCompat.setTint(this, color)
|
||||
DrawableCompat.setTintMode(this, tintMode)
|
||||
}
|
||||
|
||||
fun Drawable?.asPainter(): Painter? {
|
||||
return if (this is BitmapDrawable) {
|
||||
BitmapPainter(this.bitmap.asImageBitmap())
|
||||
} else null
|
||||
}
|
||||
Loading…
Reference in a new issue