diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillDialogBottomSheetFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillDialogBottomSheetFragment.kt new file mode 100644 index 000000000..f158347fa --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillDialogBottomSheetFragment.kt @@ -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() + } + ) + } + } + } +} + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt index 4a42b621b..de23fbd1d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt @@ -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() { @@ -99,21 +103,38 @@ class SkillsFragment : BaseMainFragment() { } 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( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SkillDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SkillDialog.kt new file mode 100644 index 000000000..adfdf2940 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SkillDialog.kt @@ -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 = { + + } + ) +} + + + + + + diff --git a/common/src/main/java/com/habitrpg/common/habitica/extensions/DrawableExtendsions.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/DrawableExtendsions.kt index 065dfaab4..b6721e22c 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/extensions/DrawableExtendsions.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/extensions/DrawableExtendsions.kt @@ -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 +} \ No newline at end of file