From 813bac92744d3a95d0804b21768ec9b2adbd19c7 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jun 2022 16:27:52 +0200 Subject: [PATCH] stufff... --- Habitica/build.gradle | 2 +- .../habitica/HabiticaBaseApplication.kt | 2 - .../ui/activities/FullProfileActivity.kt | 3 +- .../CustomizationRecyclerViewAdapter.kt | 9 +- .../ui/views/shops/PurchaseDialogContent.kt | 6 +- .../common}/habitica/extensions/ViewExt.kt | 0 .../models/responses/TaskScoringResult.kt | 42 ++++- .../habitica/views/HabiticaIconsHelper.java | 4 +- wearos/build.gradle | 2 +- wearos/src/main/AndroidManifest.xml | 1 + .../data/repositories/TaskLocalRepository.kt | 4 +- .../data/repositories/TaskRepository.kt | 5 +- .../ui/activities/TaskListActivity.kt | 52 +----- .../ui/activities/TaskResultActivity.kt | 161 ++++++++++++++++++ .../ui/viewHolders/tasks/DailyViewHolder.kt | 1 + .../ui/viewHolders/tasks/ToDoViewHolder.kt | 1 + .../habitica/ui/viewmodels/AvatarViewModel.kt | 8 +- .../ui/viewmodels/HabitDrectionViewModel.kt | 4 +- .../habitica/ui/viewmodels/MainViewModel.kt | 11 +- .../ui/viewmodels/TaskListViewModel.kt | 14 +- .../ui/viewmodels/TaskResultViewModel.kt | 19 +++ .../habitica/ui/views/TaskRewardChip.kt | 71 ++++++++ .../habitica/util/ScrollAwayBehavior.kt | 45 +++++ .../src/main/res/drawable-hdpi/experience.png | Bin 0 -> 390 bytes wearos/src/main/res/drawable-hdpi/magic.png | Bin 0 -> 422 bytes .../src/main/res/drawable-mdpi/experience.png | Bin 0 -> 324 bytes wearos/src/main/res/drawable-mdpi/magic.png | Bin 0 -> 365 bytes .../main/res/drawable-xhdpi/experience.png | Bin 0 -> 469 bytes wearos/src/main/res/drawable-xhdpi/magic.png | Bin 0 -> 529 bytes .../main/res/drawable-xxhdpi/experience.png | Bin 0 -> 569 bytes wearos/src/main/res/drawable-xxhdpi/magic.png | Bin 0 -> 647 bytes .../main/res/drawable-xxxhdpi/experience.png | Bin 0 -> 707 bytes .../src/main/res/drawable-xxxhdpi/magic.png | Bin 0 -> 743 bytes .../main/res/layout/activity_task_result.xml | 18 ++ .../src/main/res/layout/activity_tasklist.xml | 2 +- .../src/main/res/layout/task_reward_chip.xml | 24 +++ .../src/main/res/layout/task_reward_drop.xml | 25 +++ wearos/src/main/res/values/strings.xml | 5 + 38 files changed, 445 insertions(+), 96 deletions(-) rename {Habitica/src/main/java/com/habitrpg/android => common/src/main/java/com/habitrpg/common}/habitica/extensions/ViewExt.kt (100%) create mode 100644 wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskResultActivity.kt create mode 100644 wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskResultViewModel.kt create mode 100644 wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/TaskRewardChip.kt create mode 100644 wearos/src/main/java/com/habitrpg/wearos/habitica/util/ScrollAwayBehavior.kt create mode 100644 wearos/src/main/res/drawable-hdpi/experience.png create mode 100644 wearos/src/main/res/drawable-hdpi/magic.png create mode 100644 wearos/src/main/res/drawable-mdpi/experience.png create mode 100644 wearos/src/main/res/drawable-mdpi/magic.png create mode 100644 wearos/src/main/res/drawable-xhdpi/experience.png create mode 100644 wearos/src/main/res/drawable-xhdpi/magic.png create mode 100644 wearos/src/main/res/drawable-xxhdpi/experience.png create mode 100644 wearos/src/main/res/drawable-xxhdpi/magic.png create mode 100644 wearos/src/main/res/drawable-xxxhdpi/experience.png create mode 100644 wearos/src/main/res/drawable-xxxhdpi/magic.png create mode 100644 wearos/src/main/res/layout/activity_task_result.xml create mode 100644 wearos/src/main/res/layout/task_reward_chip.xml create mode 100644 wearos/src/main/res/layout/task_reward_drop.xml diff --git a/Habitica/build.gradle b/Habitica/build.gradle index a384d0889..661f8e427 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -150,7 +150,7 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" resConfigs 'en', 'bg', 'de', 'en-rGB', 'es', 'fr', 'hr-rHR', 'in', 'it', 'iw', 'ja', 'ko', 'lt', 'nl', 'pl', 'pt-rBR', 'pt-rPT', 'ru', 'tr', 'zh', 'zh-rTW' - versionCode 3520 + versionCode 4000 versionName app_version_name targetSdkVersion target_sdk diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt index 84e9a66da..920a0db64 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt @@ -18,7 +18,6 @@ import android.util.Log import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.edit import androidx.preference.PreferenceManager -import coil.annotation.ExperimentalCoilApi import com.amplitude.api.Amplitude import com.amplitude.api.Identify import com.google.firebase.analytics.FirebaseAnalytics @@ -60,7 +59,6 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife */ // endregion - @OptIn(ExperimentalCoilApi::class) override fun onCreate() { super.onCreate() registerActivityLifecycleCallbacks(this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index e72a3ece3..3bdd27755 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -14,7 +14,6 @@ import android.widget.TextView import androidx.core.content.ContextCompat import androidx.core.os.bundleOf import androidx.lifecycle.lifecycleScope -import coil.load import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ApiClient @@ -212,7 +211,7 @@ class FullProfileActivity : BaseActivity() { if (imageUrl == null || imageUrl.isEmpty()) { binding.profileImage.visibility = View.GONE } else { - binding.profileImage.load(imageUrl) + //binding.profileImage.load(imageUrl) } val blurbText = profile.blurb diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt index 916ae0372..bf8ed01e6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt @@ -5,7 +5,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat -import coil.load import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.CustomizationGridItemBinding @@ -15,16 +14,16 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.models.inventory.Customization import com.habitrpg.android.habitica.models.inventory.CustomizationSet import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.common.habitica.models.Avatar import com.habitrpg.common.habitica.views.AvatarView import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.subjects.PublishSubject -import java.util.* -import kotlin.collections.ArrayList +import java.util.Date +import java.util.EnumMap class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.RecyclerView.Adapter() { @@ -151,7 +150,7 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler this.customization = customization if (customization.type == "background" && customization.identifier == "") { - binding.imageView.load(R.drawable.no_background) + binding.imageView.setImageResource(R.drawable.no_background) binding.imageView.bitmap = null } else { binding.imageView.loadImage(customization.getIconName(userSize, hairColor)) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt index 40358da72..b21c16a72 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt @@ -5,12 +5,10 @@ import android.util.AttributeSet import android.view.Gravity import android.widget.LinearLayout import android.widget.TextView -import coil.load -import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.common.habitica.extensions.DataBindingUtils +import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.common.habitica.views.PixelArtView @@ -30,7 +28,7 @@ abstract class PurchaseDialogContent @JvmOverloads constructor( open fun setItem(item: ShopItem) { if (item.path?.contains("timeTravelBackgrounds") == true) { - imageView.load("${DataBindingUtils.BASE_IMAGE_URL}${item.imageName?.replace("icon_", "")}.gif") + // imageView.load("${DataBindingUtils.BASE_IMAGE_URL}${item.imageName?.replace("icon_", "")}.gif") val params = imageView.layoutParams params.height = 147.dpToPx(context) params.width = 140.dpToPx(context) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewExt.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/ViewExt.kt similarity index 100% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewExt.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/ViewExt.kt diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/responses/TaskScoringResult.kt b/common/src/main/java/com/habitrpg/common/habitica/models/responses/TaskScoringResult.kt index 36beae667..15aad3a07 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/models/responses/TaskScoringResult.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/models/responses/TaskScoringResult.kt @@ -1,10 +1,12 @@ package com.habitrpg.common.habitica.models.responses +import android.os.Parcel +import android.os.Parcelable import com.habitrpg.common.habitica.models.AvatarStats -class TaskScoringResult() { +class TaskScoringResult(): Parcelable { constructor(data: TaskDirectionData, stats: AvatarStats?) : this() { - hasLeveledUp = data.lvl > stats?.lvl ?: 0 + hasLeveledUp = data.lvl > (stats?.lvl ?: 0) healthDelta = data.hp - (stats?.hp ?: 0.0) if (hasLeveledUp) { experienceDelta = (stats?.toNextLevel ?: 0).toDouble() - (stats?.exp ?: 0.0) + data.exp @@ -28,4 +30,40 @@ class TaskScoringResult() { var level: Int? = null var questDamage: Double? = null var questItemsFound: Int? = null + + constructor(parcel: Parcel) : this() { + experienceDelta = parcel.readValue(Double::class.java.classLoader) as? Double + healthDelta = parcel.readValue(Double::class.java.classLoader) as? Double + goldDelta = parcel.readValue(Double::class.java.classLoader) as? Double + manaDelta = parcel.readValue(Double::class.java.classLoader) as? Double + hasLeveledUp = parcel.readByte() != 0.toByte() + level = parcel.readValue(Int::class.java.classLoader) as? Int + questDamage = parcel.readValue(Double::class.java.classLoader) as? Double + questItemsFound = parcel.readValue(Int::class.java.classLoader) as? Int + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeValue(experienceDelta) + parcel.writeValue(healthDelta) + parcel.writeValue(goldDelta) + parcel.writeValue(manaDelta) + parcel.writeByte(if (hasLeveledUp) 1 else 0) + parcel.writeValue(level) + parcel.writeValue(questDamage) + parcel.writeValue(questItemsFound) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): TaskScoringResult { + return TaskScoringResult(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } } diff --git a/common/src/main/java/com/habitrpg/common/habitica/views/HabiticaIconsHelper.java b/common/src/main/java/com/habitrpg/common/habitica/views/HabiticaIconsHelper.java index 5efcf5f0a..5263e360f 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/views/HabiticaIconsHelper.java +++ b/common/src/main/java/com/habitrpg/common/habitica/views/HabiticaIconsHelper.java @@ -31,7 +31,7 @@ public class HabiticaIconsHelper { if (imageOfExperience != null) return imageOfExperience; - int size = scaleSize(24); + int size = scaleSize(18); imageOfExperience = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(imageOfExperience); canvas.scale(displayDensity, displayDensity); @@ -45,7 +45,7 @@ public class HabiticaIconsHelper { if (imageOfMagic != null) return imageOfMagic; - int size = scaleSize(24); + int size = scaleSize(18); imageOfMagic = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(imageOfMagic); canvas.scale(displayDensity, displayDensity); diff --git a/wearos/build.gradle b/wearos/build.gradle index 0424d3541..51dea440d 100644 --- a/wearos/build.gradle +++ b/wearos/build.gradle @@ -13,7 +13,7 @@ android { applicationId "com.habitrpg.android.habitica" minSdk 26 targetSdk target_sdk - versionCode 3521 + versionCode 4001 versionName app_version_name } diff --git a/wearos/src/main/AndroidManifest.xml b/wearos/src/main/AndroidManifest.xml index 541a59495..0747d61fd 100644 --- a/wearos/src/main/AndroidManifest.xml +++ b/wearos/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt index 1df2dace4..214bb1e33 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskLocalRepository.kt @@ -48,7 +48,9 @@ class TaskLocalRepository @Inject constructor() { } else { oldList?.add(0, task) } - tasks[task.type]?.value = oldList + oldList?.let { + tasks[task.type]?.value = it + } } fun getTask(taskID: String): Flow { diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskRepository.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskRepository.kt index e0640a1be..d7da7cf13 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskRepository.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/data/repositories/TaskRepository.kt @@ -6,6 +6,7 @@ import com.habitrpg.common.habitica.models.tasks.TaskType import com.habitrpg.wearos.habitica.data.ApiClient import com.habitrpg.wearos.habitica.models.tasks.Task import com.habitrpg.wearos.habitica.models.tasks.TaskList +import com.habitrpg.wearos.habitica.models.user.User import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import javax.inject.Inject @@ -20,14 +21,14 @@ class TaskRepository @Inject constructor(val apiClient: ApiClient, val localRepo fun getTasks(taskType: TaskType): Flow> = localRepository.getTasks(taskType) - suspend fun scoreTask(task: Task, direction: TaskDirection): TaskScoringResult? { + suspend fun scoreTask(user: User?, task: Task, direction: TaskDirection): TaskScoringResult? { val id = task.id ?: return null val result = apiClient.scoreTask(id, direction.text) if (result != null) { task.completed = direction == TaskDirection.UP localRepository.updateTask(task) } - return result?.let { TaskScoringResult(it, null) } + return result?.let { TaskScoringResult(it, user?.stats) } } fun getTask(taskID: String?): Flow { diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt index 904de10a7..07db4c8fc 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt @@ -1,14 +1,8 @@ package com.habitrpg.wearos.habitica.ui.activities -import android.content.Context import android.content.Intent import android.os.Bundle -import android.util.AttributeSet -import android.view.View import androidx.activity.viewModels -import androidx.coordinatorlayout.widget.CoordinatorLayout -import androidx.core.view.ViewCompat -import androidx.wear.activity.ConfirmationActivity import androidx.wear.widget.WearableLinearLayoutManager import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ActivityTasklistBinding @@ -24,8 +18,6 @@ import com.habitrpg.wearos.habitica.ui.adapters.ToDoListAdapter import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel import com.habitrpg.wearos.habitica.util.HabiticaScrollingLayoutCallback import dagger.hilt.android.AndroidEntryPoint -import java.lang.Float.max -import java.lang.Float.min @AndroidEntryPoint class TaskListActivity: BaseActivity() { @@ -51,6 +43,10 @@ class TaskListActivity: BaseActivity scoreTask(it) } + viewModel.user.observe(this) { + + } + binding.addTaskButton.setOnClickListener { openTaskFormActivity() } } @@ -76,12 +72,7 @@ class TaskListActivity: BaseActivity } private fun showTaskScoringResult(result: TaskScoringResult) { - val intent = Intent(this, ConfirmationActivity::class.java).apply { - putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION) - putExtra(ConfirmationActivity.EXTRA_MESSAGE, result.experienceDelta?.toString()) - putExtra(ConfirmationActivity.EXTRA_ANIMATION_DURATION_MILLIS, 3000) - } - startActivity(intent) + TaskResultActivity.show(this, result) } private fun openTaskFormActivity() { @@ -127,37 +118,4 @@ class TaskListActivity: BaseActivity } } } -} - -class ScrollAwayBehavior(context: Context, attrs: AttributeSet) : - CoordinatorLayout.Behavior(context, attrs) { - - override fun onStartNestedScroll( - coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int - ): Boolean { - return axes == ViewCompat.SCROLL_AXIS_VERTICAL - } - - override fun onNestedPreScroll( - coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int - ) { - super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) - child.translationY = max(0f, min(child.height.toFloat(), child.translationY + dy)) - } - - override fun onStopNestedScroll( - coordinatorLayout: CoordinatorLayout, - child: V, - target: View, - type: Int - ) { - super.onStopNestedScroll(coordinatorLayout, child, target, type) - if (child.translationY != 0f && child.translationY != child.height.toFloat()) { - if (child.translationY < (child.height.toFloat() / 2f)) { - child.translationY = 0f - } else { - child.translationY = child.height.toFloat() - } - } - } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskResultActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskResultActivity.kt new file mode 100644 index 000000000..7923b94ae --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskResultActivity.kt @@ -0,0 +1,161 @@ +package com.habitrpg.wearos.habitica.ui.activities + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.view.Gravity +import android.view.animation.AlphaAnimation +import android.widget.GridLayout +import androidx.activity.viewModels +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.databinding.ActivityTaskResultBinding +import com.habitrpg.android.habitica.databinding.TaskRewardDropBinding +import com.habitrpg.common.habitica.extensions.dpToPx +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.models.responses.TaskScoringResult +import com.habitrpg.common.habitica.views.HabiticaIconsHelper +import com.habitrpg.wearos.habitica.ui.viewmodels.TaskResultViewModel +import com.habitrpg.wearos.habitica.ui.views.TaskRewardChip +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class TaskResultActivity : BaseActivity() { + override val viewModel: TaskResultViewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + binding = ActivityTaskResultBinding.inflate(layoutInflater) + super.onCreate(savedInstanceState) + } + + override fun onStart() { + super.onStart() + makeChips() + } + + private fun makeChips() { + binding.gridLayout.removeAllViews() + var chips = mutableListOf() + if ((viewModel.result?.healthDelta ?: 0.0) != 0.0) { + val chip = TaskRewardChip(this) + chip.set( + viewModel.result?.healthDelta, + HabiticaIconsHelper.imageOfHeartDarkBg() + ) + chips.add(chip) + } + if ((viewModel.result?.experienceDelta ?: 0.0) != 0.0) { + val chip = TaskRewardChip(this) + chip.set( + viewModel.result?.experienceDelta, + HabiticaIconsHelper.imageOfExperience() + ) + chips.add(chip) + } + if ((viewModel.result?.goldDelta ?: 0.0) != 0.0) { + val chip = TaskRewardChip(this) + chip.set( + viewModel.result?.goldDelta, + HabiticaIconsHelper.imageOfGold() + ) + chips.add(chip) + } + if ((viewModel.result?.manaDelta ?: 0.0) > 0.0) { + val chip = TaskRewardChip(this) + chip.set( + viewModel.result?.manaDelta, + HabiticaIconsHelper.imageOfMagic() + ) + chips.add(chip) + } + if ((viewModel.result?.questDamage ?: 0.0) > 0.0) { + val chip = TaskRewardChip(this) + chip.set( + viewModel.result?.questDamage, + HabiticaIconsHelper.imageOfDamage() + ) + chips.add(chip) + } + var index = 0 + var currentRow = 0 + var currentColumn = 0 + val hasDrop = viewModel.hasDrop + val margin = 6.dpToPx(this) + val chipSize = when { + hasDrop -> TaskRewardChip.Size.SMALL + chips.size <= 2 -> TaskRewardChip.Size.LARGE + chips.size == 5 -> TaskRewardChip.Size.SMALL + else -> TaskRewardChip.Size.MEDIUM + } + if (chips.size > 4 && hasDrop || (chips.size > 5 && !hasDrop)) { + chips = chips.subList(0, if (hasDrop) 4 else 5) + } + chips.forEach { + binding.gridLayout.addView(it) + it.size = chipSize + val layoutParams = GridLayout.LayoutParams() + layoutParams.height = GridLayout.LayoutParams.WRAP_CONTENT + layoutParams.width = GridLayout.LayoutParams.WRAP_CONTENT + layoutParams.setGravity(Gravity.CENTER) + layoutParams.rowSpec = GridLayout.spec(currentRow) + if (index == 0 || currentRow == 2) { + layoutParams.columnSpec = GridLayout.spec(0, 3, GridLayout.CENTER) + currentRow += 1 + } else { + layoutParams.columnSpec = GridLayout.spec(currentColumn, 1) + if (currentColumn > 0) { + layoutParams.marginStart = margin + } + currentColumn += 1 + if ((index == 2 && !hasDrop && chips.size == 4) || (index == 3 && !hasDrop && chips.size == 5)) { + currentRow += 1 + currentColumn = 0 + } + } + layoutParams.bottomMargin = margin + index += 1 + it.layoutParams = layoutParams + + val animator = AlphaAnimation(0f, 1f) + animator.startOffset = (index * 150).toLong() + 200 + animator.duration = 300 + animator.fillAfter = true + animator.fillBefore = true + it.startAnimation(animator) + } + if (hasDrop) { + val dropBinding = TaskRewardDropBinding.inflate(layoutInflater, binding.gridLayout, true) + val layoutParams = GridLayout.LayoutParams() + layoutParams.height = GridLayout.LayoutParams.WRAP_CONTENT + layoutParams.width = GridLayout.LayoutParams.WRAP_CONTENT + layoutParams.setGravity(Gravity.CENTER) + layoutParams.rowSpec = GridLayout.spec(2) + layoutParams.columnSpec = GridLayout.spec(0, 3, GridLayout.CENTER) + dropBinding.root.layoutParams = layoutParams + val elements = mutableListOf() + if ((viewModel.result?.questItemsFound?: 0) != 0) { + if (viewModel.result?.questItemsFound == 1) { + elements.add(getString(R.string.one_quest_item)) + } else { + elements.add(getString(R.string.x_quest_item, viewModel.result?.questItemsFound)) + } + } + if (viewModel.result?.drop?.key != null) { + elements.add(getString(R.string.some_x, viewModel.result?.drop?.type)) + dropBinding.imageView.loadImage(viewModel.result?.drop?.key) + } + dropBinding.textView.text = when (elements.size) { + 1 -> elements[0] + 2 -> getString(R.string.x_and_y, elements[0], elements[1]) + else -> elements.joinToString(", ") + } + } + } + + companion object { + fun show(context: Activity, result: TaskScoringResult) { + val intent = Intent(context, TaskResultActivity::class.java) + intent.putExtra("result", result) + context.startActivity(intent) + } + } +} \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/DailyViewHolder.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/DailyViewHolder.kt index d64576634..0d21e6dd0 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/DailyViewHolder.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/DailyViewHolder.kt @@ -20,6 +20,7 @@ class DailyViewHolder(itemView: View) : TaskViewHolder(itemView) { override fun bind(data: Task) { super.bind(data) + binding.checkbox.isChecked = data.completed binding.checkbox.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(itemView.context, data.mediumTaskColor)) } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/ToDoViewHolder.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/ToDoViewHolder.kt index cd00cc327..31f136b3b 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/ToDoViewHolder.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewHolders/tasks/ToDoViewHolder.kt @@ -20,6 +20,7 @@ class ToDoViewHolder(itemView: View) : TaskViewHolder(itemView) { override fun bind(data: Task) { super.bind(data) + binding.checkbox.isChecked = data.completed binding.checkbox.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(itemView.context, data.mediumTaskColor)) } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt index 7079fe085..cd186e209 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt @@ -1,9 +1,7 @@ package com.habitrpg.wearos.habitica.ui.viewmodels -import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import com.habitrpg.wearos.habitica.data.repositories.UserRepository -import com.habitrpg.wearos.habitica.models.user.User import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -16,9 +14,5 @@ class AvatarViewModel @Inject constructor( userRepository, exceptionBuilder ) { - var user: LiveData - - init { - user = userRepository.getUser().asLiveData() - } + var user = userRepository.getUser().asLiveData() } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/HabitDrectionViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/HabitDrectionViewModel.kt index e3236e0a5..093d35367 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/HabitDrectionViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/HabitDrectionViewModel.kt @@ -21,9 +21,11 @@ class HabitDrectionViewModel @Inject constructor( val taskID = savedStateHandle.get("task_id") val task = taskRepository.getTask(taskID).asLiveData() + val user = userRepository.getUser().asLiveData() + fun scoreTask(direction: TaskDirection) { viewModelScope.launch(exceptionBuilder.userFacing(this)) { - task.value?.let { taskRepository.scoreTask(it, direction) } + task.value?.let { taskRepository.scoreTask(user.value, it, direction) } } } } diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt index 46a545873..b38f54a7a 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt @@ -1,12 +1,9 @@ package com.habitrpg.wearos.habitica.ui.viewmodels -import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope -import com.habitrpg.common.habitica.api.HostConfig import com.habitrpg.wearos.habitica.data.repositories.TaskRepository import com.habitrpg.wearos.habitica.data.repositories.UserRepository -import com.habitrpg.wearos.habitica.models.user.User import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -14,19 +11,13 @@ import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( - val hostConfig: HostConfig, userRepository: UserRepository, val taskRepository: TaskRepository, exceptionBuilder: ExceptionHandlerBuilder ) : BaseViewModel(userRepository, exceptionBuilder) { - val isAuthenticated: Boolean - get() { - return hostConfig.hasAuthentication() - } - var user: LiveData + var user = userRepository.getUser().asLiveData() init { - user = userRepository.getUser().asLiveData() viewModelScope.launch(exceptionBuilder.userFacing(this)) { userRepository.retrieveUser() taskRepository.retrieveTasks() diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt index 697898af4..7e4a69c7f 100644 --- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt @@ -1,6 +1,5 @@ package com.habitrpg.wearos.habitica.ui.viewmodels -import androidx.lifecycle.LiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope @@ -22,17 +21,16 @@ class TaskListViewModel @Inject constructor( userRepository: UserRepository, exceptionBuilder: ExceptionHandlerBuilder ) : BaseViewModel(userRepository, exceptionBuilder) { + val taskType = TaskType.from(savedStateHandle.get("task_type")) + val tasks = taskRepository.getTasks(taskType ?: TaskType.HABIT).asLiveData() + val user = userRepository.getUser() + .asLiveData() + fun scoreTask(task: Task, direction: TaskDirection, onResult: (TaskScoringResult?) -> Unit) { viewModelScope.launch(exceptionBuilder.userFacing(this)) { - val result = taskRepository.scoreTask(task, direction) + val result = taskRepository.scoreTask(user.value, task, direction) onResult(result) } } - var tasks: LiveData> - val taskType = TaskType.from(savedStateHandle.get("task_type")) - - init { - tasks = taskRepository.getTasks(taskType ?: TaskType.HABIT).asLiveData() - } } \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskResultViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskResultViewModel.kt new file mode 100644 index 000000000..af1ffab3f --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskResultViewModel.kt @@ -0,0 +1,19 @@ +package com.habitrpg.wearos.habitica.ui.viewmodels + +import androidx.lifecycle.SavedStateHandle +import com.habitrpg.common.habitica.models.responses.TaskScoringResult +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 TaskResultViewModel @Inject constructor(savedStateHandle: SavedStateHandle, userRepository: UserRepository, + exceptionBuilder: ExceptionHandlerBuilder +) : BaseViewModel(userRepository, exceptionBuilder) { + val hasDrop: Boolean + get() { + return result?.drop?.key?.isNotBlank() == true || (result?.questItemsFound ?: 0) > 0 + } + val result = savedStateHandle.get("result") +} diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/TaskRewardChip.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/TaskRewardChip.kt new file mode 100644 index 000000000..99184f337 --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/views/TaskRewardChip.kt @@ -0,0 +1,71 @@ +package com.habitrpg.wearos.habitica.ui.views + +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Bitmap +import android.util.AttributeSet +import android.util.TypedValue +import android.view.Gravity +import android.widget.LinearLayout +import androidx.core.content.ContextCompat +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.databinding.TaskRewardChipBinding +import com.habitrpg.android.habitica.extensions.round +import com.habitrpg.android.habitica.extensions.setScaledPadding +import com.habitrpg.common.habitica.extensions.layoutInflater +import java.math.RoundingMode +import java.text.NumberFormat + +class TaskRewardChip @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : LinearLayout(context, attrs) { + enum class Size { + SMALL, + MEDIUM, + LARGE + } + + val binding = TaskRewardChipBinding.inflate(context.layoutInflater, this) + + var size: Size = Size.MEDIUM + set(value) { + field = value + binding.textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, when (field) { + Size.SMALL -> 14f + Size.MEDIUM -> 16f + Size.LARGE -> 20f + }) + when (field) { + Size.SMALL -> setScaledPadding(context, 10, 9, 10, 9) + Size.MEDIUM -> setScaledPadding(context, 17, 9, 17, 9) + Size.LARGE -> setScaledPadding(context, 21, 12, 21, 12) + } + } + + init { + background = ContextCompat.getDrawable(context, R.drawable.row_background) + gravity = Gravity.CENTER + } + + fun set(value: Double?, icon: Bitmap) { + binding.iconView.setImageBitmap(icon) + var text = formatter.format(value?.round(1)) + if (text.firstOrNull() == '0') { + text = text.substring(1) + } + binding.textView.text = text + backgroundTintList = if ((value ?: 0.0) > 0.0) { + ColorStateList.valueOf(ContextCompat.getColor(context, R.color.watch_green_100)) + } else { + ColorStateList.valueOf(ContextCompat.getColor(context, R.color.watch_red_100)) + } + } + + companion object { + private val formatter = NumberFormat.getInstance().apply { + maximumFractionDigits = 1 + roundingMode = RoundingMode.UP + isGroupingUsed = true + } + } +} \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ScrollAwayBehavior.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ScrollAwayBehavior.kt new file mode 100644 index 000000000..8e9033c65 --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ScrollAwayBehavior.kt @@ -0,0 +1,45 @@ +package com.habitrpg.wearos.habitica.util + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.view.ViewCompat +import java.lang.Float +import kotlin.Boolean +import kotlin.Int +import kotlin.IntArray + +class ScrollAwayBehavior(context: Context, attrs: AttributeSet) : + CoordinatorLayout.Behavior(context, attrs) { + + override fun onStartNestedScroll( + coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int + ): Boolean { + return axes == ViewCompat.SCROLL_AXIS_VERTICAL + } + + override fun onNestedPreScroll( + coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int + ) { + super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) + child.translationY = + Float.max(0f, Float.min(child.height.toFloat(), child.translationY + dy)) + } + + override fun onStopNestedScroll( + coordinatorLayout: CoordinatorLayout, + child: V, + target: View, + type: Int + ) { + super.onStopNestedScroll(coordinatorLayout, child, target, type) + if (child.translationY != 0f && child.translationY != child.height.toFloat()) { + if (child.translationY < (child.height.toFloat() / 2f)) { + child.translationY = 0f + } else { + child.translationY = child.height.toFloat() + } + } + } +} \ No newline at end of file diff --git a/wearos/src/main/res/drawable-hdpi/experience.png b/wearos/src/main/res/drawable-hdpi/experience.png new file mode 100644 index 0000000000000000000000000000000000000000..a0f4a06b786766da2d6ca8c9dff32cc20aa28ece GIT binary patch literal 390 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s3?yAI>n{UREa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaOm0(?ST-3xsF&sX@rOc{h0EB#-p3_^>*BFlk-N+9t)QGd4i{lD1%d4=`= z)rNl$<$j#2`2SSx|4k16A8!49b@sza@_%nG`Ty)dU_iDzWio+ z{uje5FE3tt%rwbQ_mOk^WG~&`!Vryw4!?yBcAqp&cc>{e@x85Q`qJsxzf*0N#kubC z_2O?oO`G8ym3AcdT{hPY%cWB`mn&_0r`CPT_G7`t-#jyl4{-fqz56>lcF)rn&lQe; zIeR9u>(3Hh>$0VPmY1?gMRMtxs^7ofeL=A6L5gr$oPPMyT29h$h*t@kY}i>dg> b=h^rEW$^aQGiSB}dWFH$)z4*}Q$iB}ve&Vw literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/drawable-hdpi/magic.png b/wearos/src/main/res/drawable-hdpi/magic.png new file mode 100644 index 0000000000000000000000000000000000000000..88a1f56071d3ddb61b0e0797a20f2c228cfca36a GIT binary patch literal 422 zcmV;X0a^ZuP)Px#T~JI^MMrQ6Oanr`q(M(d)$G@~zkHgu&o(y5KXL&_AZ!P^i{E zpV5KJ@VDReW3}H`tk}$FJh}h?01I?dPE!DY_h3Sgpx+Q7%8U!hF8}}l&`Cr=R4C7t z(%BA!AP_)N*NToHAd6b<|9@r&m(~cFme&(*U?53;UiF<-MI0Yck(lKGP)4IL0Ti*Q zHB%&vQKP91hB5l$nvTIRMj7XnhQb9#x$HHi{)tHiBj)m$M;KfFf~l@~su zvy#dSZ_!x@$<`CwQ@93Lj1gi*#^{7w(*ql@UDrK#)LGl&3)J7?>?%K&pGOCSQ^|De zEIZ$nG@DAZT2)_1>vRd4yAJ9Qwj@bW2ec;m+Nc)bLH_?>IR7lY`PG-?8!!nFzvvRV Qi2wiq07*qoM6N<$f=ENU3;+NC literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/drawable-mdpi/experience.png b/wearos/src/main/res/drawable-mdpi/experience.png new file mode 100644 index 0000000000000000000000000000000000000000..cd22d0e25b2d182a3090e9d28ec674a3c6a9439a GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaN*1AIbU-3xsF&sX@rSmFONWe{4f{C}y+|D`~-5?EXXDERL{>c35n|91xb zU#<85Z1eBM${*(`{l7f<&0_OEHx~bYwC(A1<+ppw=G>nHvXi?c$S;^dz~TLZ{S68C z6&woJ8SVuNH+Z@@hDcn_o!~9htRTQ@*vPRb@kjEz`b!yyoQ(IShF=%i5>%WQnskfn z34>ymi?+$L`atE2p(Ro=ng?wBSQ@K%RsDad`ec@5rCz$K6tpV&iGHvxcgn=IQ}$<8-C|$*mG$2O&YX6jTNpfD L{an^LB{Ts5`#p(r literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/drawable-mdpi/magic.png b/wearos/src/main/res/drawable-mdpi/magic.png new file mode 100644 index 0000000000000000000000000000000000000000..e9cc12874ead77b9768994c06879f611aa4fe7ae GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaNR1AIbU-3xqFr<~WEc1~mJInAkOHK(1`n0g+_(3pN+WBPHesi!nRf@d_R zoY9(g7APLG?xxY~3)4?OTX*B_R*-qiUd3ucwP+h{WaE z3orSa6$IP@1GTcI_n&3Wy!yTV6rWk(fhC{2=R9dUDROjvW?s1Pp0g|4v_1<3DXnh3 z)b0OTYHytCsV!H|>DaAXX>u-O!lvI6;x#X;^) z4C~IxyaaLr1AIbU-3xsFFH`{DK+Y zE8IWWpfF#+G2zkYFS$VbxjkJRLo81BUb#4_S%JqP@b=cFdX7w8VgLU-n{$@AM`xW_ zT>QM_#08W0#d}RfllAy*cSS`vN@kb#tl&CRur$$Wr9|N01&KbD>l1w}@6S(mvgCh0 zBOqjMV*l)b5W{O_PoE{VcJWDQm+sssHpiJoV&1pS)uze^MAGN9nXY+%cOByg3+28< z-sA6XT=<>VlPBeDQF7Nm?!u8~V_z2+c4goB|5rVX{W*2ra@z&`DOzslKTJ?Az8|*j zy;_f*=qzV;f#j&5l{ZVju+~L7?fm(ktznDK`Fvh~?FgY)|GxT^G^s8-b5c`8XKt|c zG!d<2&xJ;5rd|e9Zy7AUr@sY&j0`b literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/drawable-xhdpi/magic.png b/wearos/src/main/res/drawable-xhdpi/magic.png new file mode 100644 index 0000000000000000000000000000000000000000..3bb78d2afbbf6338e2df8a6528f0298969bdecc7 GIT binary patch literal 529 zcmV+s0`C2ZP)Px#Y*0*8MMrQSD@jB_R5;7E)Z3PVAQXV%3d_?5L?q0^jLy9OJI)5Fv_QHU?p*6%esc0~ z_|K6ZKdBNR@#qXt#=Q&xqGk?ekfsO@V>{;J@%GAC*mU01v>Y=Cn2X1oroE!s`OUj$s-XGsY=x%w%@e&2=hrM% zz+8D$smX5|kJ=G`P)Px#PEbr#MMrQ<|ED4Uqa^>MApf5r|E44Vrz8KRBmbr% z|E41UrX&BRBLAi%|GZlN(vkn&tNyl3?wcV0%YfgJAOGjW|E@Om&6NDWY3rae_Mjro zNW+f+000bhQchCL2Z&Z)U!6wCA6yc=TfQWayqKI)?8JbF)FY%Mgt|`Kw*vUZVsFQ$+qplo0UQf)0E`YZ~VHLQ3>=-oW zd?=|RXKk0jZ27Dr_pk&G>9d{krJ9EhJ^LVVSnf-ve6MiE{(;?y8O~n$RpDTVA>89^ zm0Q(lEoIL6y>hGacrP);%=oD$34bu-i^ZL`auB!TPJsfD+Xe?#OQRVq0 zo>|K;j_s1J&Sk2d(uWRm)mDiMfgMbct-eaSsn+>vnjl|&lwsu^X4Cyw^;XhKdg7+# zclBBl2rJhXyt3Px#V^B;~MMrQ^z>)h{NKU%H%GY(6-$0aJb!6 zsns=?$fwlmoX_fX!|Xhz+lI{Wx<;1L0000BbW%=J0Pi>ug=feh`rn{n4%trt00FB> zL_t(Y$JN%`vVtHKfZ^2CDKrz$$9nAw%$LJnT+nax!*^$%Z&;^p%1M;xB(?!-Tn zg@oLK6UrMQ6QOJd3K4L)Cc90bv^$S zS!Mw$d6&3Ig%Uak>7vBWUb-l;vzD&P=UDI#rLpnSt;&hERbnmOlr3$GO&VG#dr(r= zjjPm)%}PF9O?g*XN1?EXrRdDkFC}fKu~?<#P`Y1B+NNop z*Yzl*<)KtovMA*p8?4kyH|2zt=vXEQIskh8niwsY~yZN}pWu2=`LSAjoSq$ab zOi$h*+Cs8rq3w&rOU$R-B%1r4Z`R>(ljy>Rb(*WK2^+_3ee2O}65ZC(ZW8T)EZ0qQ*_6IGpKFm|S&))z5002ovPDHLkV1n>HKC1u# literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/drawable-xxxhdpi/experience.png b/wearos/src/main/res/drawable-xxxhdpi/experience.png new file mode 100644 index 0000000000000000000000000000000000000000..a69d690d97337119264f5ba9a77e5723cf6e0157 GIT binary patch literal 707 zcmeAS@N?(olHy`uVBq!ia0vp^o*>M@3?$vw{(c9fSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?slr1o(uwx)=ETU#k3n83ZZ)U##?hx$^%d3Lp|Fz9;Jci$Ie zznk6uoo@VccFMoihX0@J`hTS0|I6cV7FqmQq}0oN1!Ox{NswPKL&N+3_Z{}jEJ(O& z-~|+9V)k@#42d|r_QvgPO$q`HiKm@A7A^32|9{!+$yU3xFU)+oF7*B{-^~j&jGhGw z_(t#RSh6Z5#8WjeBvsXIs*7-FWoMvjpi5|AQi$h|6ZTjE!oa%EPEYRr{sVB(32&y{%)V(ITdg_GXf7e`GHSt1d7wS3MD zktL?9a$ddm^Lb^(x9HPau{)kllVR*IEeTas$$zI1JKa9@mdMqHZUxw!x5ww&ve zb=M6OlG`*nxwgQ@wAzzR0QY!lO%nXeLh;${zS!=XWpqIyGW~; zFujw3H_z2;%S;HkTs#op6#q0h_07VIJIC>!W2iXSz(L8yL*8|qR=L?P)nq00004XF*Lt006O% z3;baP00001b5ch_0Itp)=>Px#S5Qn;MMrQTI^%Rh<^^0000AbW%=J0Phe%W`M{d-;YTM{?~aeLlGjVuhJVwenJT2AoNm7FvebdFFeoF zi)|hczGN-A`(BvM(~E7MB=ll)_JNH!`@q)r#MQUjNYl5DKCu0=K6UdkTQ-#jr|ZXT zb18N4aobXI@Cn;mO09h{w?WC)7YQ4bEPW^tHdeCp$+nEvYstp9v1MJ?q?SIE$hP{^ z)f-=Y=e4v9*gjK)DAwwCJqKCq?S2BnQJK*lyAY*4!G(`~G@ zy?&8}jg{)`j&IM#OW+%fe0#Rf2SRszd$z92X-RMTc5Gcf4K2%((mOuwep@TWy%q{DZ((r>M^XBzq4T$T7%QoQLTOMg+V$(@jrGN%HX(6R zky2C-8J$93+Ky6nu>-^7td=ra?9)dcPZ6_yJYDxzD%ph89VKRqZLp)naIvp{6%kk8 z=C~oPJE#H}WEj3b%?tnl002ovPDHLkV1mpJU#b8A literal 0 HcmV?d00001 diff --git a/wearos/src/main/res/layout/activity_task_result.xml b/wearos/src/main/res/layout/activity_task_result.xml new file mode 100644 index 000000000..6d7e7b7ca --- /dev/null +++ b/wearos/src/main/res/layout/activity_task_result.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/layout/activity_tasklist.xml b/wearos/src/main/res/layout/activity_tasklist.xml index 4f6206294..04a6733c4 100644 --- a/wearos/src/main/res/layout/activity_tasklist.xml +++ b/wearos/src/main/res/layout/activity_tasklist.xml @@ -14,5 +14,5 @@ android:layout_width="match_parent" android:layout_height="38dp" android:layout_gravity="center|bottom" - app:layout_behavior="com.habitrpg.wearos.habitica.ui.activities.ScrollAwayBehavior"/> + app:layout_behavior="com.habitrpg.wearos.habitica.util.ScrollAwayBehavior"/> \ No newline at end of file diff --git a/wearos/src/main/res/layout/task_reward_chip.xml b/wearos/src/main/res/layout/task_reward_chip.xml new file mode 100644 index 000000000..c6cb51cf7 --- /dev/null +++ b/wearos/src/main/res/layout/task_reward_chip.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/layout/task_reward_drop.xml b/wearos/src/main/res/layout/task_reward_drop.xml new file mode 100644 index 000000000..260ba6949 --- /dev/null +++ b/wearos/src/main/res/layout/task_reward_drop.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/values/strings.xml b/wearos/src/main/res/values/strings.xml index 4c236dd9d..5c3a60937 100644 --- a/wearos/src/main/res/values/strings.xml +++ b/wearos/src/main/res/values/strings.xml @@ -2,4 +2,9 @@ OK Syncing Account from Phone How did you do? + You found… + 1 Quest item + %d Quest items + %s and %s + some %s \ No newline at end of file