mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-18 11:49:01 +00:00
Implement fainting
This commit is contained in:
parent
b7742bb6c3
commit
f464e61b9a
19 changed files with 226 additions and 31 deletions
|
|
@ -40,9 +40,12 @@
|
|||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.TaskDetailActivity" />
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.HabitDirectionActivity" />
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.TaskResultActivity" />
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.RYAActivity" />
|
||||
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.AvatarActivity" />
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.StatsActivity" />
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.FaintActivity" />
|
||||
|
||||
<activity android:name="com.habitrpg.wearos.habitica.ui.activities.SettingsActivity" />
|
||||
|
||||
<activity android:name="androidx.wear.activity.ConfirmationActivity" />
|
||||
|
|
|
|||
|
|
@ -1,17 +1,39 @@
|
|||
package com.habitrpg.wearos.habitica
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import com.habitrpg.common.habitica.extensions.setupCoil
|
||||
import com.habitrpg.common.habitica.helpers.MarkdownParser
|
||||
import com.habitrpg.common.habitica.views.HabiticaIconsHelper
|
||||
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
||||
import com.habitrpg.wearos.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.wearos.habitica.ui.activities.FaintActivity
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltAndroidApp
|
||||
class MainApplication : Application() {
|
||||
|
||||
@Inject lateinit var userRepository: UserRepository
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
HabiticaIconsHelper.init(this)
|
||||
MarkdownParser.setup(this)
|
||||
setupCoil()
|
||||
|
||||
MainScope().launch {
|
||||
userRepository.getUser().onEach {
|
||||
if (it.isDead && BaseActivity.currentActivityClassName != FaintActivity::class.java.name) {
|
||||
val intent = Intent(this@MainApplication, FaintActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(intent)
|
||||
}
|
||||
}.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ import com.squareup.moshi.JsonClass
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class User: Avatar {
|
||||
val isDead: Boolean
|
||||
get() = (stats?.hp ?: 0.0) <= 0.0
|
||||
override val currentMount: String?
|
||||
get() = items?.currentMount
|
||||
override val currentPet: String?
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import com.habitrpg.wearos.habitica.ui.viewmodels.BaseViewModel
|
|||
import com.habitrpg.wearos.habitica.ui.views.IndeterminateProgressView
|
||||
|
||||
abstract class BaseActivity<B: ViewBinding, VM: BaseViewModel> : ComponentActivity() {
|
||||
companion object {
|
||||
var currentActivityClassName: String? = null
|
||||
}
|
||||
private lateinit var wrapperBinding: ActivityWrapperBinding
|
||||
protected lateinit var binding: B
|
||||
abstract val viewModel: VM
|
||||
|
|
@ -35,6 +38,11 @@ abstract class BaseActivity<B: ViewBinding, VM: BaseViewModel> : ComponentActivi
|
|||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
currentActivityClassName = this.localClassName
|
||||
}
|
||||
|
||||
fun startAnimatingProgress() {
|
||||
if (progressView == null) {
|
||||
progressView = IndeterminateProgressView(this)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package com.habitrpg.wearos.habitica.ui.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.databinding.ActivityFaintBinding
|
||||
import com.habitrpg.wearos.habitica.ui.viewmodels.FaintViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class FaintActivity: BaseActivity<ActivityFaintBinding, FaintViewModel>() {
|
||||
override val viewModel: FaintViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityFaintBinding.inflate(layoutInflater)
|
||||
super.onCreate(savedInstanceState)
|
||||
binding.continueButton.setOnClickListener {
|
||||
binding.continueButton.isEnabled = false
|
||||
startAnimatingProgress()
|
||||
lifecycleScope.launch(CoroutineExceptionHandler { _, _ ->
|
||||
stopAnimatingProgress()
|
||||
binding.continueButton.isEnabled = true
|
||||
}) {
|
||||
viewModel.revive()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
binding.hpBar.setPercentageValues(0f, 50f)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.hpBar.animateProgress(50f, 2000)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.habitrpg.wearos.habitica.ui.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import com.habitrpg.android.habitica.databinding.ActivityRyaBinding
|
||||
import com.habitrpg.wearos.habitica.ui.viewmodels.RYAViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class RYAActivity: BaseActivity<ActivityRyaBinding, RYAViewModel>() {
|
||||
override val viewModel: RYAViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
binding = ActivityRyaBinding.inflate(layoutInflater)
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
|
@ -38,16 +38,16 @@ class StatsActivity : BaseActivity<ActivityStatsBinding, StatsViewModel>() {
|
|||
}
|
||||
|
||||
private fun updateBarViews(stats: Stats) {
|
||||
binding.hpBar.setPercentageValues(stats.hp?.toInt() ?: 0, stats.maxHealth ?: 0)
|
||||
binding.hpBar.setPercentageValues(stats.hp?.toFloat() ?: 0f, stats.maxHealth?.toFloat() ?: 0f)
|
||||
binding.hpBar.animateProgress()
|
||||
|
||||
binding.expBar.setPercentageValues(stats.exp?.toInt() ?: 0, stats.toNextLevel ?: 0)
|
||||
binding.expBar.setPercentageValues(stats.exp?.toFloat() ?: 0f, stats.toNextLevel?.toFloat() ?: 0f)
|
||||
binding.expBar.animateProgress()
|
||||
|
||||
if ((stats.lvl ?: 0) < 10) {
|
||||
binding.mpBar.visibility = View.GONE
|
||||
} else {
|
||||
binding.mpBar.setPercentageValues(stats.mp?.toInt() ?: 0, stats.maxMP ?: 0)
|
||||
binding.mpBar.setPercentageValues(stats.mp?.toFloat() ?: 0f, stats.maxMP?.toFloat() ?: 0f)
|
||||
binding.mpBar.animateProgress()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||
|
||||
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
||||
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class FaintViewModel @Inject constructor(userRepository: UserRepository,
|
||||
exceptionBuilder: ExceptionHandlerBuilder
|
||||
) : BaseViewModel(userRepository, exceptionBuilder) {
|
||||
suspend fun revive() {
|
||||
userRepository.revive()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||
|
||||
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
||||
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class RYAViewModel @Inject constructor(userRepository: UserRepository,
|
||||
exceptionBuilder: ExceptionHandlerBuilder
|
||||
) : BaseViewModel(userRepository, exceptionBuilder) {
|
||||
|
||||
}
|
||||
|
|
@ -3,12 +3,15 @@ package com.habitrpg.wearos.habitica.ui.views
|
|||
import android.animation.PropertyValuesHolder
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.RectF
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
|
||||
class CircularProgressView(
|
||||
context: Context?,
|
||||
|
|
@ -16,31 +19,34 @@ class CircularProgressView(
|
|||
) : View(context, attrs) {
|
||||
private val ovalSpace = RectF()
|
||||
private var ovalSize = (resources.displayMetrics.heightPixels / 2)
|
||||
private var currentPercentage = 55
|
||||
private var PERCENTAGE_DIVIDER = 180
|
||||
private var currentPercentage = 55f
|
||||
private var PERCENTAGE_DIVIDER = 180f
|
||||
private val ARC_FULL_ROTATION_DEGREE = 360
|
||||
val attributes = context?.theme?.obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.CircularProgressView,
|
||||
0, 0
|
||||
)
|
||||
private val offset = attributes?.getInt(R.styleable.CircularProgressView_offset, 0)
|
||||
private val offset = attributes?.getDimension(R.styleable.CircularProgressView_offset, 0f)?.toInt()
|
||||
private val backgroundArcColor = attributes?.getColor(R.styleable.CircularProgressView_backgroundArcColor, 0) ?: Color.GRAY
|
||||
private var fillArcColor = attributes?.getColor(R.styleable.CircularProgressView_arcFillColor, 0) ?: Color.GRAY
|
||||
|
||||
set(value) {
|
||||
field = value
|
||||
fillArcPaint.color = fillArcColor
|
||||
}
|
||||
|
||||
private val parentArcPaint = Paint().apply {
|
||||
style = Paint.Style.STROKE
|
||||
isAntiAlias = true
|
||||
color = backgroundArcColor
|
||||
strokeWidth = 10f
|
||||
strokeWidth = 5f.dpToPx(context)
|
||||
}
|
||||
|
||||
private var fillArcPaint = Paint().apply {
|
||||
style = Paint.Style.STROKE
|
||||
isAntiAlias = true
|
||||
color = fillArcColor
|
||||
strokeWidth = 10f
|
||||
strokeWidth = 5f.dpToPx(context)
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
}
|
||||
|
||||
|
|
@ -82,36 +88,29 @@ class CircularProgressView(
|
|||
|
||||
fun setBarColor(barColor: Int) {
|
||||
fillArcColor = context?.resources?.getColor(barColor, null) ?: backgroundArcColor
|
||||
fillArcPaint = Paint().apply {
|
||||
style = Paint.Style.STROKE
|
||||
isAntiAlias = true
|
||||
color = fillArcColor
|
||||
strokeWidth = 10f
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
}
|
||||
}
|
||||
|
||||
fun setPercentageValues(currentValue: Int, maxValue: Int) {
|
||||
fun setPercentageValues(currentValue: Float, maxValue: Float) {
|
||||
currentPercentage = currentValue
|
||||
PERCENTAGE_DIVIDER = maxValue
|
||||
}
|
||||
|
||||
fun animateProgress() {
|
||||
val currentPercent: Int = currentPercentage
|
||||
fun animateProgress(startValue: Float = 0f, animationDuration: Long = 1000) {
|
||||
val currentPercent = currentPercentage
|
||||
val valuesHolder = PropertyValuesHolder.ofFloat(
|
||||
PERCENTAGE_VALUE_HOLDER,
|
||||
1f,
|
||||
startValue,
|
||||
currentPercent.toFloat()
|
||||
)
|
||||
|
||||
val animator = ValueAnimator().apply {
|
||||
setValues(valuesHolder)
|
||||
duration = 1000
|
||||
duration = animationDuration
|
||||
interpolator = AccelerateDecelerateInterpolator()
|
||||
|
||||
addUpdateListener {
|
||||
val percentage = it.getAnimatedValue(PERCENTAGE_VALUE_HOLDER) as Float
|
||||
currentPercentage = percentage.toInt()
|
||||
currentPercentage = percentage
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +121,6 @@ class CircularProgressView(
|
|||
const val PERCENTAGE_VALUE_HOLDER = "percentage"
|
||||
}
|
||||
|
||||
private fun getCurrentAngleToFill() = if(currentPercentage > 0) {(ARC_FULL_ROTATION_DEGREE.toFloat() * (currentPercentage.toFloat() / PERCENTAGE_DIVIDER.toFloat()))} else {1f}
|
||||
private fun getCurrentAngleToFill() = if(currentPercentage > 0) {(ARC_FULL_ROTATION_DEGREE.toFloat() * (currentPercentage / PERCENTAGE_DIVIDER))} else {1f}
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
wearos/src/main/res/drawable-mdpi/broken_heart.png
Normal file
BIN
wearos/src/main/res/drawable-mdpi/broken_heart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
wearos/src/main/res/drawable-xhdpi/broken_heart.png
Normal file
BIN
wearos/src/main/res/drawable-xhdpi/broken_heart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
wearos/src/main/res/drawable-xxhdpi/broken_heart.png
Normal file
BIN
wearos/src/main/res/drawable-xxhdpi/broken_heart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6 KiB |
47
wearos/src/main/res/layout/activity_faint.xml
Normal file
47
wearos/src/main/res/layout/activity_faint.xml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.habitrpg.wearos.habitica.ui.views.CircularProgressView
|
||||
android:id="@+id/hp_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:arcFillColor="@color/hp_bar_color"
|
||||
app:backgroundArcColor="@color/bar_background_color"
|
||||
app:offset="4dp" />
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center">
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/broken_heart"
|
||||
android:layout_marginBottom="@dimen/spacing_medium"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/you_ran_out_of_hp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
style="@style/Text.Subheader1"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/faint_description"
|
||||
android:textColor="@color/watch_gray_500"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="@dimen/spacing_large"
|
||||
android:gravity="center"/>
|
||||
<Button
|
||||
android:id="@+id/continue_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/continue_text"
|
||||
style="@style/ChipButton.Small.Red"/>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
7
wearos/src/main/res/layout/activity_rya.xml
Normal file
7
wearos/src/main/res/layout/activity_rya.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
android:layout_height="match_parent"
|
||||
app:arcFillColor="@color/hp_bar_color"
|
||||
app:backgroundArcColor="@color/bar_background_color"
|
||||
app:offset="10" />
|
||||
app:offset="5dp" />
|
||||
|
||||
<com.habitrpg.wearos.habitica.ui.views.CircularProgressView
|
||||
android:id="@+id/exp_bar"
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
android:layout_height="match_parent"
|
||||
app:arcFillColor="@color/exp_bar_color"
|
||||
app:backgroundArcColor="@color/bar_background_color"
|
||||
app:offset="28" />
|
||||
app:offset="14dp" />
|
||||
|
||||
<com.habitrpg.wearos.habitica.ui.views.CircularProgressView
|
||||
android:id="@+id/mp_bar"
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
android:layout_height="match_parent"
|
||||
app:arcFillColor="@color/mp_bar_color"
|
||||
app:backgroundArcColor="@color/bar_background_color"
|
||||
app:offset="46" />
|
||||
app:offset="23dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<attr name="drawFromTop" format="boolean" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="CircularProgressView">
|
||||
<attr name="offset" format="integer" />
|
||||
<attr name="offset" format="dimension" />
|
||||
<attr name="backgroundArcColor" format="color" />
|
||||
<attr name="arcFillColor" format="color" />
|
||||
</declare-styleable>
|
||||
|
|
|
|||
|
|
@ -14,4 +14,7 @@
|
|||
<string name="other_options">Other options</string>
|
||||
<string name="create_account">Create account</string>
|
||||
<string name="sign_in_password">Sign in with password</string>
|
||||
<string name="continue_text">Continue</string>
|
||||
<string name="you_ran_out_of_hp">You ran out of HP</string>
|
||||
<string name="faint_description">You lost a Level, Exp, and Gold. Don’t give up!</string>
|
||||
</resources>
|
||||
|
|
@ -18,19 +18,40 @@
|
|||
<item name="android:paddingVertical">@dimen/row_padding_vertical</item>
|
||||
<item name="android:background">@drawable/row_background</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="fontFamily">@string/medium</item>
|
||||
<item name="fontFamily">sans-serif-medium</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:minHeight">52dp</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:letterSpacing">0.05</item>
|
||||
<item name="android:drawablePadding">8dp</item>
|
||||
<item name="android:foreground">?selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="ChipButton.Small">
|
||||
<item name="android:paddingHorizontal">@dimen/row_padding_horizontal</item>
|
||||
<item name="android:paddingVertical">@dimen/row_padding_vertical</item>
|
||||
<item name="android:background">@drawable/row_background</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="fontFamily">sans-serif-medium</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:minHeight">32dp</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:letterSpacing">0.05</item>
|
||||
<item name="android:drawablePadding">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ChipButton.Purple">
|
||||
<item name="android:backgroundTint">@color/watch_purple_100</item>
|
||||
</style>
|
||||
|
||||
<style name="ChipButton.Red">
|
||||
<item name="android:backgroundTint">@color/watch_red_200</item>
|
||||
</style>
|
||||
|
||||
<style name="ChipButton.Small.Red">
|
||||
<item name="android:backgroundTint">@color/watch_red_200</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
</style>
|
||||
|
||||
<style name="Text" />
|
||||
|
||||
<style name="Text.Subheader1">
|
||||
|
|
|
|||
Loading…
Reference in a new issue