diff --git a/wearos/src/main/AndroidManifest.xml b/wearos/src/main/AndroidManifest.xml index a4f5654b2..69aefbe0f 100644 --- a/wearos/src/main/AndroidManifest.xml +++ b/wearos/src/main/AndroidManifest.xml @@ -40,9 +40,12 @@ + + + diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt index 2a1938abd..79a1a37cc 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainApplication.kt @@ -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() + } } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/models/user/User.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/models/user/User.kt index 4a3dca5ab..6941ab48e 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/models/user/User.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/models/user/User.kt @@ -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? diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt index c42da762e..85f019de4 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt @@ -13,6 +13,9 @@ import com.habitrpg.wearos.habitica.ui.viewmodels.BaseViewModel import com.habitrpg.wearos.habitica.ui.views.IndeterminateProgressView abstract class BaseActivity : 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 : ComponentActivi } } + override fun onResume() { + super.onResume() + currentActivityClassName = this.localClassName + } + fun startAnimatingProgress() { if (progressView == null) { progressView = IndeterminateProgressView(this) diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/FaintActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/FaintActivity.kt new file mode 100644 index 000000000..0f1ad2d6b --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/FaintActivity.kt @@ -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() { + 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) + } +} \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt new file mode 100644 index 000000000..79eeb3a91 --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/RYAActivity.kt @@ -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() { + override val viewModel: RYAViewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityRyaBinding.inflate(layoutInflater) + super.onCreate(savedInstanceState) + } +} \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/StatsActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/StatsActivity.kt index 39426f2fc..a6fe343c0 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/StatsActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/StatsActivity.kt @@ -38,16 +38,16 @@ class StatsActivity : BaseActivity() { } 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() } } diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/FaintViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/FaintViewModel.kt new file mode 100644 index 000000000..93d03195f --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/FaintViewModel.kt @@ -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() + } +} diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt new file mode 100644 index 000000000..b09aa2db8 --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/RYAViewModel.kt @@ -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) { + +} diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/CircularProgressView.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/CircularProgressView.kt index f48981fce..8b0a895c3 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/CircularProgressView.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/CircularProgressView.kt @@ -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} } diff --git a/wearos/src/main/res/drawable-mdpi/broken_heart.png b/wearos/src/main/res/drawable-mdpi/broken_heart.png new file mode 100644 index 000000000..cee972753 Binary files /dev/null and b/wearos/src/main/res/drawable-mdpi/broken_heart.png differ diff --git a/wearos/src/main/res/drawable-xhdpi/broken_heart.png b/wearos/src/main/res/drawable-xhdpi/broken_heart.png new file mode 100644 index 000000000..72a0eba89 Binary files /dev/null and b/wearos/src/main/res/drawable-xhdpi/broken_heart.png differ diff --git a/wearos/src/main/res/drawable-xxhdpi/broken_heart.png b/wearos/src/main/res/drawable-xxhdpi/broken_heart.png new file mode 100644 index 000000000..8793117b6 Binary files /dev/null and b/wearos/src/main/res/drawable-xxhdpi/broken_heart.png differ diff --git a/wearos/src/main/res/layout/activity_faint.xml b/wearos/src/main/res/layout/activity_faint.xml new file mode 100644 index 000000000..b92303049 --- /dev/null +++ b/wearos/src/main/res/layout/activity_faint.xml @@ -0,0 +1,47 @@ + + + + + + + +