From 6dfcc446a7452cbcd741483ee3df3eabf55dd9e3 Mon Sep 17 00:00:00 2001 From: Anita Woodruff Date: Fri, 8 May 2020 17:41:58 +0100 Subject: [PATCH 01/32] Add content descriptions to menu drawer items - Now Talkback reads out 'Notifications, [number]', 'Messages', and 'Settings' if a user swipes through the navigation drawer with Talkback enabled (previously the content descriptions were not set). --- Habitica/res/layout/drawer_main.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Habitica/res/layout/drawer_main.xml b/Habitica/res/layout/drawer_main.xml index 60a527613..ce2b4dde3 100644 --- a/Habitica/res/layout/drawer_main.xml +++ b/Habitica/res/layout/drawer_main.xml @@ -68,7 +68,8 @@ android:background="@color/transparent" android:src="@drawable/menu_notifications" android:layout_centerVertical="true" - android:clickable="false" /> + android:clickable="false" + android:contentDescription="@string/notifications" /> + android:clickable="false" + android:contentDescription="@string/inbox" /> - + android:layout_centerVertical="true" + android:contentDescription="@string/PS_settings_title" /> Date: Sun, 21 Jun 2020 17:25:52 -0500 Subject: [PATCH 02/32] Fixed can't add more than one task on challenge form --- .../android/habitica/ui/activities/ChallengeFormActivity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt index 0e6392b68..a3a82706e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt @@ -460,6 +460,11 @@ class ChallengeFormActivity : BaseActivity() { Task.TYPE_TODO -> addTodo else -> addReward } + if(!isExistingTask){ + // If the task is new we create a unique id for it + // Doing it we solve the issue #1278 + task.id = UUID.randomUUID().toString() + } challengeTasks.addTaskUnder(task, taskAbove) From 241599a785859170a75823dc64687068ef1eaf8c Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 13 Jul 2020 17:28:19 +0200 Subject: [PATCH 03/32] fix various crashes --- Habitica/build.gradle | 2 +- .../res/layout/activity_adventure_guide.xml | 1 - Habitica/res/layout/pet_detail_item.xml | 1 - Habitica/res/values/styles.xml | 5 ++- .../habitica/helpers/PurchaseHandler.kt | 20 +++++++---- .../HabiticaFirebaseMessagingService.java | 35 ------------------- .../HabiticaFirebaseMessagingService.kt | 33 +++++++++++++++++ .../ui/activities/AdventureGuideActivity.kt | 4 +++ .../habitica/ui/activities/LoginActivity.kt | 5 +++ .../habitica/ui/activities/MainActivity.kt | 14 ++++++-- .../inventory/PetDetailRecyclerAdapter.kt | 8 ++++- .../inventory/StableRecyclerAdapter.kt | 24 +++++++------ .../ui/views/dialogs/HabiticaAlertDialog.kt | 4 --- .../habitica/widget/TaskListFactory.kt | 3 ++ 14 files changed, 95 insertions(+), 64 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 89040842d..beb6c6f61 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -162,7 +162,7 @@ android { multiDexEnabled true 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 2462 + versionCode 2466 versionName "2.7" } diff --git a/Habitica/res/layout/activity_adventure_guide.xml b/Habitica/res/layout/activity_adventure_guide.xml index 7674b7f6c..5feab0ad1 100644 --- a/Habitica/res/layout/activity_adventure_guide.xml +++ b/Habitica/res/layout/activity_adventure_guide.xml @@ -89,7 +89,6 @@ android:layout_marginBottom="@dimen/spacing_medium" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:progressBackgroundTint="@color/gray_600" - android:progressBackgroundTintMode="src_over" android:progressTint="@color/yellow_50"/> \ No newline at end of file diff --git a/Habitica/res/values/styles.xml b/Habitica/res/values/styles.xml index 7b7f43b96..44fe19c92 100644 --- a/Habitica/res/values/styles.xml +++ b/Habitica/res/values/styles.xml @@ -309,7 +309,10 @@ diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt index ada17a27b..296dc705e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt @@ -6,6 +6,7 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.proxy.CrashlyticsProxy import org.solovyev.android.checkout.* import java.util.* +import javax.annotation.Nonnull class PurchaseHandler(activity: Activity, val crashlyticsProxy: CrashlyticsProxy) { private val billing = HabiticaBaseApplication.getInstance(activity.applicationContext)?.billing @@ -73,20 +74,25 @@ class PurchaseHandler(activity: Activity, val crashlyticsProxy: CrashlyticsProxy } private fun getProduct(type: String, identifiers: List, onSuccess: ((Inventory.Product) -> Unit)) { - inventory?.load(Inventory.Request.create() - .loadAllPurchases().loadSkus(type, identifiers)) { products -> + loadInventory(type, identifiers, Inventory.Callback { products -> val purchases = products.get(type) - if (!purchases.supported) return@load + if (!purchases.supported) return@Callback onSuccess(purchases) - } + }) } private fun getSKU(type: String, identifier: String, onSuccess: ((Sku) -> Unit)) { - inventory?.load(Inventory.Request.create() - .loadAllPurchases().loadSkus(type, listOf(identifier))) { products -> + loadInventory(type, listOf(identifier), Inventory.Callback { products -> val purchases = products.get(type) - if (!purchases.supported) return@load + if (!purchases.supported) return@Callback purchases.skus.firstOrNull()?.let { onSuccess(it) } + }) + } + + private fun loadInventory(type: String, skus: List, callback: Inventory.Callback) { + val request = Inventory.Request.create().loadAllPurchases().loadSkus(type, skus) + if (request != null) { + inventory?.load(request, callback) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.java deleted file mode 100644 index 008888d84..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.habitrpg.android.habitica.helpers.notifications; - -import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; -import com.habitrpg.android.habitica.HabiticaApplication; - -import java.util.Objects; - -import javax.inject.Inject; - -/** - * Created by keithholliday on 6/24/16. - */ -public class HabiticaFirebaseMessagingService extends FirebaseMessagingService { - - @Inject - public PushNotificationManager pushNotificationManager; - - @Override - public void onMessageReceived(RemoteMessage remoteMessage) { - Objects.requireNonNull(HabiticaApplication.Companion.getUserComponent()).inject(this); - pushNotificationManager.displayNotification(remoteMessage); - } - - @Override - public void onNewToken(String s) { - super.onNewToken(s); - Objects.requireNonNull(HabiticaApplication.Companion.getUserComponent()).inject(this); - String refreshedToken = FirebaseInstanceId.getInstance().getToken(); - if (refreshedToken != null) { - pushNotificationManager.setRefreshedToken(refreshedToken); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt new file mode 100644 index 000000000..c8cc4127e --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt @@ -0,0 +1,33 @@ +package com.habitrpg.android.habitica.helpers.notifications + +import com.google.firebase.iid.FirebaseInstanceId +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.RemoteMessage +import com.habitrpg.android.habitica.HabiticaApplication +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.components.UserComponent +import java.util.* +import javax.inject.Inject + +class HabiticaFirebaseMessagingService : FirebaseMessagingService() { + + private val userComponent: UserComponent? + get() = HabiticaBaseApplication.userComponent + + @Inject + internal lateinit var pushNotificationManager: PushNotificationManager + + override fun onMessageReceived(remoteMessage: RemoteMessage) { + userComponent?.inject(this) + pushNotificationManager.displayNotification(remoteMessage) + } + + override fun onNewToken(s: String) { + super.onNewToken(s) + userComponent?.inject(this) + val refreshedToken = FirebaseInstanceId.getInstance().token + if (refreshedToken != null) { + pushNotificationManager.refreshedToken = refreshedToken + } + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt index df1bef019..7553900bc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.ui.activities import android.graphics.Paint +import android.graphics.PorterDuff import android.os.Build import android.os.Bundle import android.text.Html @@ -94,6 +95,9 @@ class AdventureGuideActivity : BaseActivity() { val completed = achievements.count { it.earned } binding.progressBar.max = achievements.size binding.progressBar.progress = completed + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + binding.progressBar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER + } if (completed > 0) { binding.progressTextview.text = getString(R.string.percent_completed, ((completed / achievements.size.toFloat()) * 100).toInt()) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt index c407e8d7e..51e65a860 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt @@ -31,6 +31,7 @@ import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.GooglePlayServicesUtil import com.google.android.gms.common.Scopes +import com.google.firebase.analytics.FirebaseAnalytics import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R @@ -369,6 +370,10 @@ class LoginActivity : BaseActivity(), Consumer { HabiticaBaseApplication.reloadUserComponent() + if (isRegistering) { + FirebaseAnalytics.getInstance(this).logEvent("user_registered", null) + } + compositeSubscription.add(userRepository.retrieveUser(true) .subscribe(Consumer { if (userAuthResponse.newUser) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 09092169f..7be8e44b6 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -159,7 +159,11 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { @SuppressLint("ObsoleteSdkInt") public override fun onCreate(savedInstanceState: Bundle?) { - launchTrace = FirebasePerformance.getInstance().newTrace("MainActivityLaunch") + try { + launchTrace = FirebasePerformance.getInstance().newTrace("MainActivityLaunch") + } catch (_: IllegalStateException) { + + } launchTrace?.start() super.onCreate(savedInstanceState) @@ -358,11 +362,15 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { val quest = user?.party?.quest if (quest?.completed?.isNotBlank() == true) { - compositeSubscription.add(inventoryRepository.getQuestContent(user?.party?.quest?.completed ?: "").firstElement().subscribe { + compositeSubscription.add(inventoryRepository.getQuestContent(user?.party?.quest?.completed ?: "").firstElement().subscribe(Consumer { QuestCompletedDialog.showWithQuest(this, it) userRepository.updateUser(user, "party.quest.completed", "").subscribe(Consumer {}, RxErrorHandler.handleEmptyError()) - }) + }, RxErrorHandler.handleEmptyError())) + } + + if (user?.flags?.welcomed == false) { + compositeSubscription.add(userRepository.updateUser(user, "flags.welcomed", true).subscribe(Consumer {}, RxErrorHandler.handleEmptyError())) } if (appConfigManager.enableAdventureGuide()) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index 88487a78b..b917f88c7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.ui.adapter.inventory import android.content.Context +import android.graphics.PorterDuff import android.graphics.drawable.BitmapDrawable import android.view.View import android.view.ViewGroup @@ -107,10 +108,14 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B this.trainedProgressbar.visibility = View.GONE this.imageView.alpha = 0.1f } + if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { + trainedProgressbar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER + } imageView.background = null val trained = ownedPet?.trained ?: 0 DataBindingUtils.loadImage(imageName) { - val drawable = BitmapDrawable(context?.resources, if (trained == 0) it.extractAlpha() else it) + val resources = context?.resources ?: return@loadImage + val drawable = BitmapDrawable(resources, if (trained == 0) it.extractAlpha() else it) Observable.just(drawable) .observeOn(AndroidSchedulers.mainThread()) .subscribe(Consumer { @@ -125,6 +130,7 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B } val context = context ?: return val menu = BottomSheetMenu(context) + menu.setTitle(animal?.text) menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.equip))) if (canRaiseToMount) { menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.feed))) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index c0d783c4e..4245d0ed5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -55,19 +55,23 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) { val obj = this.itemList[position] - if (obj == "header") { - (holder as? StableHeaderViewHolder)?.bind() - } else if (obj.javaClass == String::class.java) { - if (obj == "Standard") { - var params = holder.itemView.layoutParams as GridLayoutManager.LayoutParams - params.height = 135 - holder.itemView.layoutParams = params + when { + obj == "header" -> { + (holder as? StableHeaderViewHolder)?.bind() } - (holder as? SectionViewHolder)?.bind(obj as? String ?: "") + obj.javaClass == String::class.java -> { + if (obj == "Standard") { + val params = holder.itemView.layoutParams as GridLayoutManager.LayoutParams + params.height = 135 + holder.itemView.layoutParams = params + } + (holder as? SectionViewHolder)?.bind(obj as? String ?: "") - } else { - (obj as? Animal)?.let { (holder as? StableViewHolder)?.bind(it) } + } + else -> { + (obj as? Animal)?.let { (holder as? StableViewHolder)?.bind(it) } + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt index 17ffb9a41..f8625df1c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt @@ -265,9 +265,7 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. if (dialogQueue.firstOrNull() == currentDialog) { dialogQueue.removeAt(0) } - Log.i("SHOWNEXT", dialogQueue.toString()) if (dialogQueue.size > 0) { - Log.i("FOUNDONE", dialogQueue[0].toString()) if ((dialogQueue[0].context as? Activity) == null || (dialogQueue[0].context as? Activity)?.isFinishing == false) { dialogQueue[0].show() } @@ -277,9 +275,7 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. private fun addToQueue(dialog: HabiticaAlertDialog) { if (dialogQueue.isEmpty()) { dialog.show() - Log.i("SHOWIMMEDIATELY", dialog.toString()) } - Log.i("ADDTOQUEUE", dialog.toString()) dialogQueue.add(dialog) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt index e980ea7ff..2c9ea4ebc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListFactory.kt @@ -36,6 +36,9 @@ abstract class TaskListFactory internal constructor(val context: Context, intent } private fun loadData() { + if (!this::taskRepository.isInitialized) { + return + } val mainHandler = Handler(context.mainLooper) mainHandler.post { taskRepository.getCurrentUserTasks(taskType) From 2dbbac0b41c0372b27af92a3af909ac6df65aa80 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 13 Jul 2020 17:28:26 +0200 Subject: [PATCH 04/32] display pet name in menu popup --- Habitica/res/layout/menu_bottom_sheet.xml | 18 +++++++++++++++++- Habitica/res/values/dimens.xml | 2 +- .../habitica/ui/menu/BottomSheetMenu.kt | 19 +++++++++++++------ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Habitica/res/layout/menu_bottom_sheet.xml b/Habitica/res/layout/menu_bottom_sheet.xml index 943ae2746..fcc654b20 100644 --- a/Habitica/res/layout/menu_bottom_sheet.xml +++ b/Habitica/res/layout/menu_bottom_sheet.xml @@ -1,7 +1,23 @@ + + \ No newline at end of file diff --git a/Habitica/res/values/dimens.xml b/Habitica/res/values/dimens.xml index 4287e6204..7df9b73c1 100644 --- a/Habitica/res/values/dimens.xml +++ b/Habitica/res/values/dimens.xml @@ -58,7 +58,7 @@ 2dp 84dp 120dp - 28dp + 20dp 68dp 65dp 81dp diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/menu/BottomSheetMenu.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/menu/BottomSheetMenu.kt index 7d72eb0de..7c6b0f99b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/menu/BottomSheetMenu.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/menu/BottomSheetMenu.kt @@ -5,13 +5,15 @@ import android.view.View import android.widget.LinearLayout import com.google.android.material.bottomsheet.BottomSheetDialog import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.databinding.MenuBottomSheetBinding class BottomSheetMenu(context: Context) : BottomSheetDialog(context), View.OnClickListener { - private var contentView = layoutInflater.inflate(R.layout.menu_bottom_sheet, null) as LinearLayout + private var binding = MenuBottomSheetBinding.inflate(layoutInflater) private var runnable: ((Int) -> Unit)? = null init { - setContentView(contentView) + setContentView(binding.root) + binding.titleView.visibility = View.GONE } fun setSelectionRunnable(runnable: (Int) -> Unit) { @@ -24,19 +26,24 @@ class BottomSheetMenu(context: Context) : BottomSheetDialog(context), View.OnCli } } + override fun setTitle(title: CharSequence?) { + binding.titleView.text = title + binding.titleView.visibility = View.VISIBLE + } + fun addMenuItem(menuItem: BottomSheetMenuItem) { - val item = menuItem.inflate(this.context, layoutInflater, this.contentView) + val item = menuItem.inflate(this.context, layoutInflater, this.binding.menuItems) item.setOnClickListener(this) - this.contentView.addView(item) + this.binding.menuItems.addView(item) } fun removeMenuItem(index: Int) { - this.contentView.removeViewAt(index) + this.binding.menuItems.removeViewAt(index) } override fun onClick(v: View) { if (this.runnable != null) { - val index = this.contentView.indexOfChild(v) + val index = this.binding.menuItems.indexOfChild(v) if (index != -1) { runnable?.let { it(index) } this.dismiss() From 96682e106f3d24ef9daec8298b40113fef452b38 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 08:38:49 +0200 Subject: [PATCH 05/32] Improve stable overview and add new dialog for unhatched --- .../res/layout/dialog_pet_suggest_hatch.xml | 64 ++++++++++++++++++ Habitica/res/values/strings.xml | 10 ++- .../habitica/extensions/Animal-Extensions.kt | 1 + .../inventory/PetDetailRecyclerAdapter.kt | 32 ++++++++- .../inventory/StableRecyclerAdapter.kt | 53 ++++++++++++--- .../stable/PetDetailRecyclerFragment.kt | 9 +++ .../stable/StableRecyclerFragment.kt | 13 ++-- .../ui/views/dialogs/PetSuggestHatchDialog.kt | 67 +++++++++++++++++++ 8 files changed, 230 insertions(+), 19 deletions(-) create mode 100644 Habitica/res/layout/dialog_pet_suggest_hatch.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt diff --git a/Habitica/res/layout/dialog_pet_suggest_hatch.xml b/Habitica/res/layout/dialog_pet_suggest_hatch.xml new file mode 100644 index 000000000..57ebae355 --- /dev/null +++ b/Habitica/res/layout/dialog_pet_suggest_hatch.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index f9d45dcce..7e60c15a6 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -1027,8 +1027,8 @@ %d%% Complete Create a Task Complete a Task - Hatch a Pet - Feed a Pet + Hatch a new pet + Feed a pet Purchase Equipment Add a task for something you would like to accomplish this week Check off any of your tasks to earn rewards @@ -1058,4 +1058,10 @@ You already have everything you need for all %s pets. Are you sure you want to purchase %d %ss? Equip View Onboarding Tasks + You\'ll need a %s Egg and %s Potion to hatch this pet + You can use a %s Egg and a %s Potion to hatch this pet + Hatch Pet + Unhatched Pet + Magic Potions + Magic Potion diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt index f8cb2c6bc..102b47cc1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt @@ -14,6 +14,7 @@ fun Animal.getTranslatedType(c: Context?): String { "quest" -> c?.getString(R.string.quest).toString() "wacky" -> c?.getString(R.string.wacky).toString() "special" -> c?.getString(R.string.special).toString() + "premium" -> c?.getString(R.string.magic_potion).toString() else -> { type } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index b917f88c7..b66dd1c0b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -10,16 +10,19 @@ import android.widget.TextView import com.facebook.drawee.view.SimpleDraweeView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.events.commands.FeedCommand +import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.models.inventory.Mount -import com.habitrpg.android.habitica.models.inventory.Pet +import com.habitrpg.android.habitica.models.inventory.* +import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.bindView import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem +import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog +import com.habitrpg.android.habitica.ui.views.dialogs.PetSuggestHatchDialog import io.reactivex.BackpressureStrategy import io.reactivex.Flowable import io.reactivex.Observable @@ -38,12 +41,15 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B private var existingMounts: RealmResults? = null private var ownedPets: Map? = null private var ownedMounts: Map? = null + private var ownedItems: Map? = null private val equipEvents = PublishSubject.create() fun getEquipFlowable(): Flowable { return equipEvents.toFlowable(BackpressureStrategy.DROP) } + var animalIngredientsRetriever: ((Animal) -> Pair)? = null + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PetViewHolder { return PetViewHolder(parent.inflate(R.layout.pet_detail_item)) } @@ -68,6 +74,12 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B this.ownedPets = ownedPets notifyDataSetChanged() } + + fun setOwnedItems(ownedItems: Map) { + this.ownedItems = ownedItems + notifyDataSetChanged() + } + inner class PetViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView), View.OnClickListener { var animal: Pet? = null var ownedPet: OwnedPet? = null @@ -88,6 +100,11 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B return false } + private val canHatch: Boolean + get() { + return ownedItems?.get(animal?.animal + "-eggs") != null && ownedItems?.get(animal?.color + "-hatchingPotions") != null + } + init { itemView.setOnClickListener(this) } @@ -126,6 +143,7 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B override fun onClick(v: View) { if (!this.isOwned) { + showRequirementsDialog() return } val context = context ?: return @@ -148,5 +166,15 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B } menu.show() } + + private fun showRequirementsDialog() { + val context = context ?: return + val dialog = PetSuggestHatchDialog(context) + animal?.let { + val ingredients = animalIngredientsRetriever?.invoke(it) + dialog.configure(it, ingredients?.first, ingredients?.second, canHatch) + } + dialog.show() + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index 4245d0ed5..7d6bdcca0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.GridLayoutManager import com.facebook.drawee.view.SimpleDraweeView import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.FeedCommand import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler @@ -18,11 +19,17 @@ import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.fragments.inventory.stable.StableFragmentDirections import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder import com.habitrpg.android.habitica.ui.views.NPCBannerView +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.Consumer +import io.reactivex.subjects.PublishSubject +import org.greenrobot.eventbus.EventBus class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter() { @@ -30,6 +37,11 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< var itemType: String? = null var context: Context? = null var activity: MainActivity? = null + private val equipEvents = PublishSubject.create() + + fun getEquipFlowable(): Flowable { + return equipEvents.toFlowable(BackpressureStrategy.DROP) + } private var itemList: List = ArrayList() @@ -120,7 +132,8 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< fun bind(item: Animal) { this.animal = item - titleView.text = if (item.type == "special") { + val isIndividualAnimal = item.type == "special" || animal?.type == "wacky" + titleView.text = if (isIndividualAnimal) { item.text } else { item.animal @@ -131,27 +144,33 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< this.ownedTextView.alpha = 1.0f val imageName = if (itemType == "pets") { - "Pet_Egg_" + item.animal + if (isIndividualAnimal) { + "social_Pet-" + animal?.key + } else { + "Pet_Egg_" + item.animal + } } else { "Mount_Icon_" + item.key } context?.let { - - var owned = item.numberOwned - var totalNum = item.totalNumber - + val owned = item.numberOwned + val totalNum = item.totalNumber this.ownedTextView.text = context?.getString(R.string.pet_ownership_fraction, owned, totalNum) this.ownedTextView.background = context?.getDrawable(R.drawable.layout_rounded_bg_shopitem_price) this.ownedTextView.setTextColor(ContextCompat.getColor(it, R.color.black) ) - ownedTextView.visibility = if (animal?.type == "special") View.GONE else View.VISIBLE + ownedTextView.visibility = if (isIndividualAnimal) View.GONE else View.VISIBLE imageView.background = null - - DataBindingUtils.loadImage(imageName) { - val drawable = BitmapDrawable(context?.resources, it) + val numberOwned = item.numberOwned == 0 + DataBindingUtils.loadImage(imageName) {bitmap -> + val drawable = if (isIndividualAnimal) { + BitmapDrawable(context?.resources, if (numberOwned) bitmap.extractAlpha() else bitmap) + } else { + BitmapDrawable(context?.resources, bitmap) + } Observable.just(drawable) .observeOn(AndroidSchedulers.mainThread()) .subscribe(Consumer { @@ -175,6 +194,20 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< override fun onClick(v: View) { val animal = this.animal if (animal != null) { + if (animal.type == "special" || animal.type == "wacky") { + if (animal.numberOwned == 0) return + val context = context ?: return + val menu = BottomSheetMenu(context) + menu.setTitle(animal.text) + menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.equip))) + menu.setSelectionRunnable { + animal.let { + equipEvents.onNext(it.key) + } + } + menu.show() + return + } val color = if (animal.type == "special") animal.color else null if (animal.numberOwned > 0) { if (itemType == "pets") { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt index 55e96dc9c..f2d6fc3fd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt @@ -9,9 +9,12 @@ import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.events.commands.FeedCommand import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.inventory.Egg +import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.models.inventory.Mount import com.habitrpg.android.habitica.models.inventory.Pet import com.habitrpg.android.habitica.models.user.Items +import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapter @@ -83,6 +86,11 @@ class PetDetailRecyclerFragment : BaseMainFragment() { compositeSubscription.add(adapter.getEquipFlowable() .flatMap { key -> inventoryRepository.equip(user, "pet", key) } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) + adapter.animalIngredientsRetriever = { + val egg = inventoryRepository.getItems(Egg::class.java, arrayOf(it.animal), null).firstElement().blockingGet().firstOrNull() + val potion = inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(it.color), null).firstElement().blockingGet().firstOrNull() + Pair(egg as? Egg, potion as? HatchingPotion) + } view.post { setGridSpanCount(view.width) } } @@ -122,6 +130,7 @@ class PetDetailRecyclerFragment : BaseMainFragment() { return@map mountMap } .subscribe(Consumer { adapter.setOwnedMounts(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(inventoryRepository.getOwnedItems().subscribe(Consumer { adapter.setOwnedItems(it) }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(inventoryRepository.getPets(animalType, animalGroup, animalColor).firstElement().subscribe(Consumer> { adapter.updateData(it) }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(inventoryRepository.getMounts(animalType, animalGroup, animalColor).subscribe(Consumer> { adapter.setExistingMounts(it) }, RxErrorHandler.handleEmptyError())) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt index b82bf9c92..147a49006 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt @@ -12,10 +12,7 @@ import com.habitrpg.android.habitica.extensions.getTranslatedType import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.Animal -import com.habitrpg.android.habitica.models.user.OwnedMount -import com.habitrpg.android.habitica.models.user.OwnedObject -import com.habitrpg.android.habitica.models.user.OwnedPet -import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.models.user.* import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment @@ -91,6 +88,12 @@ class StableRecyclerFragment : BaseFragment() { adapter?.context = context recyclerView?.adapter = adapter recyclerView?.itemAnimator = SafeDefaultItemAnimator() + + adapter?.let { + compositeSubscription.add(it.getEquipFlowable() + .flatMap { key -> inventoryRepository.equip(user, if (itemType == "pets") "pet" else "mount", key) } + .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) + } } this.loadItems() @@ -146,7 +149,7 @@ class StableRecyclerFragment : BaseFragment() { var lastAnimal: Animal = unsortedAnimals[0] ?: return items var lastSectionTitle = "" for (animal in unsortedAnimals) { - val identifier = if (animal.animal.isNotEmpty() && animal.type != "special") animal.animal else animal.key + val identifier = if (animal.animal.isNotEmpty() && (animal.type != "special" && animal.type != "wacky")) animal.animal else animal.key val lastIdentifier = if (lastAnimal.animal.isNotEmpty()) lastAnimal.animal else lastAnimal.key if (identifier != lastIdentifier || animal === unsortedAnimals[unsortedAnimals.size - 1]) { if (!((lastAnimal.type == "premium" || lastAnimal.type == "special") && lastAnimal.numberOwned == 0)) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt new file mode 100644 index 000000000..f8641c21e --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt @@ -0,0 +1,67 @@ +package com.habitrpg.android.habitica.ui.views.dialogs + +import android.content.Context +import android.graphics.drawable.BitmapDrawable +import android.view.LayoutInflater +import com.facebook.drawee.view.SimpleDraweeView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.databinding.DialogPetSuggestHatchBinding +import com.habitrpg.android.habitica.helpers.MainNavigationController +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.inventory.Animal +import com.habitrpg.android.habitica.models.inventory.Egg +import com.habitrpg.android.habitica.models.inventory.HatchingPotion +import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.functions.Consumer + +class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) { + + + private lateinit var binding: DialogPetSuggestHatchBinding + + init { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater + inflater?.let { binding = DialogPetSuggestHatchBinding.inflate(it) } + setAdditionalContentView(binding.root) + } + + fun configure(pet: Animal, egg: Egg?, potion: HatchingPotion?, canHatch: Boolean) { + DataBindingUtils.loadImage(binding.eggView, "Pet_Egg_${pet.animal}") + DataBindingUtils.loadImage(binding.hatchingPotionView, "Pet_HatchingPotion_${pet.color}") + binding.petTitleView.text = pet.text + + + if (canHatch) { + binding.descriptionView.text = context.getString(R.string.can_hatch_pet, + egg?.text ?: pet.animal.capitalize(), + potion?.text ?: pet.color.capitalize()) + addButton(R.string.hatch_pet, true, false) { _, _ -> + val thisPotion = potion ?: return@addButton + val thisEgg = egg ?: return@addButton + (getActivity() as? MainActivity)?.hatchPet(thisPotion, thisEgg) + } + setTitle(R.string.hatch_pet_title) + } else { + binding.descriptionView.text = context.getString(R.string.suggest_pet_hatch, + egg?.text ?: pet.animal.capitalize(), + potion?.text ?: pet.color.capitalize()) + setTitle(R.string.unhatched_pet) + } + + addButton(R.string.close, !canHatch) + + val imageName = "social_Pet-${pet.animal}-${pet.color}" + DataBindingUtils.loadImage(imageName) { + val resources = context.resources ?: return@loadImage + val drawable = BitmapDrawable(resources, it.extractAlpha()) + Observable.just(drawable) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(Consumer { + binding.petView.background = drawable + }, RxErrorHandler.handleEmptyError()) + } + } +} From e7f321d3e585dbda576d32d365204682794a97a8 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 08:38:55 +0200 Subject: [PATCH 06/32] update dependencies --- Habitica/build.gradle | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index beb6c6f61..748221bb1 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -64,7 +64,7 @@ dependencies { compileOnly 'com.github.pengrad:jdk9-deps:1.0' //App Compatibility and Material Design implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.0.0' + implementation 'com.google.android.material:material:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' // Emojis @@ -104,7 +104,7 @@ dependencies { } //Tests testImplementation 'junit:junit:4.12' - testImplementation 'androidx.test:core:1.0.0' + testImplementation 'androidx.test:core:1.2.0' testImplementation "com.google.truth:truth:1.0.1" testImplementation 'org.assertj:assertj-core:2.6.0' testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2' @@ -119,11 +119,11 @@ dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2' releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2' //Push Notifications - implementation 'com.google.firebase:firebase-core:17.2.2' - implementation 'com.google.firebase:firebase-messaging:20.1.0' - implementation 'com.google.firebase:firebase-config:19.1.1' - implementation 'com.google.firebase:firebase-perf:19.0.5' - implementation 'com.google.android.gms:play-services-auth:17.0.0' + implementation 'com.google.firebase:firebase-core:17.4.4' + implementation 'com.google.firebase:firebase-messaging:20.2.3' + implementation 'com.google.firebase:firebase-config:19.2.0' + implementation 'com.google.firebase:firebase-perf:19.0.7' + implementation 'com.google.android.gms:play-services-auth:18.0.0' implementation 'io.realm:android-adapters:3.1.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.multidex:multidex:2.0.1' @@ -132,8 +132,8 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.0' implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0" - implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2' - implementation 'androidx.navigation:navigation-ui-ktx:2.2.2' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' implementation "androidx.paging:paging-runtime-ktx:2.1.2" implementation 'com.plattysoft.leonids:LeonidsLib:1.3.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3' @@ -162,8 +162,8 @@ android { multiDexEnabled true 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 2466 - versionName "2.7" + versionCode 2472 + versionName "2.7.1" } viewBinding { From a9d8ca24c37225b4aae1acd6ff0c186d8478cf4e Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 10:34:43 +0200 Subject: [PATCH 07/32] Allow users to unequip some equipment from customization screen --- .../ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt | 4 +++- .../inventory/customization/AvatarEquipmentFragment.kt | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt index 68f6edf29..442c8fd26 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt @@ -65,6 +65,8 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R fun setEquipment(newEquipmentList: List) { this.equipmentList = newEquipmentList.toMutableList() + val emptyEquipment = Equipment() + equipmentList.add(0, emptyEquipment) this.notifyDataSetChanged() } @@ -104,7 +106,7 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R } } - if (activeEquipment == equipment.key) { + if (activeEquipment == equipment.key || (activeEquipment?.contains("base_0") == true && equipment.key?.isNotBlank() != true)) { binding.wrapper.background = itemView.context.getDrawable(R.drawable.layout_rounded_bg_gray_700_brand_border) } else { binding.wrapper.background = itemView.context.getDrawable(R.drawable.layout_rounded_bg_gray_700) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt index 2e55d5d05..c67412958 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt @@ -40,7 +40,8 @@ class AvatarEquipmentFragment : BaseMainFragment() { compositeSubscription.add(adapter.getSelectCustomizationEvents() .flatMap { equipment -> - inventoryRepository.equip(user, if (user?.preferences?.costume == true) "costume" else "equipped", equipment.key ?: "") + val key = (if (equipment.key?.isNotBlank() != true) activeEquipment else equipment.key) ?: "" + inventoryRepository.equip(user, if (user?.preferences?.costume == true) "costume" else "equipped", key) } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(adapter.getUnlockCustomizationEvents() From 871ed519706c9e36876c969d1c0f8b13688469f3 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 10:34:51 +0200 Subject: [PATCH 08/32] Fix scrolling issue on shops screen --- .../habitica/ui/fragments/inventory/shops/ShopsFragment.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt index 8280b1510..5dae10324 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt @@ -54,7 +54,6 @@ open class ShopsFragment : BaseMainFragment() { this.usesTabLayout = false tabLayout?.visibility = View.GONE viewPager.currentItem = lockTab ?: 0 - viewPager.setOnTouchListener { _, _ -> true } } context?.let { FirebaseAnalytics.getInstance(it).logEvent("open_shop", bundleOf(Pair("shopIndex", lockTab))) } @@ -85,7 +84,7 @@ open class ShopsFragment : BaseMainFragment() { val fragment = ShopFragment() - fragment.shopIdentifier = when (position) { + fragment.shopIdentifier = when (lockTab ?: position) { 0 -> Shop.MARKET 1 -> Shop.QUEST_SHOP 2 -> Shop.SEASONAL_SHOP @@ -97,7 +96,7 @@ open class ShopsFragment : BaseMainFragment() { return fragment } - override fun getCount(): Int = 4 + override fun getCount(): Int = if (lockTab != null) 1 else 4 override fun getPageTitle(position: Int): CharSequence? { return when (position) { @@ -118,6 +117,6 @@ open class ShopsFragment : BaseMainFragment() { private fun updateCurrencyView(user: User) { currencyView.gold = user.stats?.gp ?: 0.0 currencyView.gems = user.gemCount.toDouble() - currencyView.hourglasses = user.hourglassCount?.toDouble() ?: 0.0 + currencyView.hourglasses = user.hourglassCount.toDouble() } } From cc41b3853eca4e4e4fb2620c97d25b4c54ce94cb Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 16:53:37 +0200 Subject: [PATCH 09/32] =?UTF-8?q?rename=20To-Dos=20to=20To=20Do=E2=80=99s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Habitica/build.gradle | 2 +- Habitica/res/layout/todo_item_card.xml | 2 +- Habitica/res/values-da/strings.xml | 10 ++++----- Habitica/res/values-de/strings.tutorial.xml | 4 ++-- Habitica/res/values-de/strings.xml | 18 +++++++-------- .../res/values-en-rGB/strings.tutorial.xml | 4 ++-- Habitica/res/values-en-rGB/strings.xml | 18 +++++++-------- Habitica/res/values-in/strings.tutorial.xml | 4 ++-- Habitica/res/values-in/strings.xml | 12 +++++----- Habitica/res/values-it/strings.tutorial.xml | 4 ++-- Habitica/res/values-it/strings.xml | 20 ++++++++--------- Habitica/res/values-ja/strings.tutorial.xml | 4 ++-- Habitica/res/values-ja/strings.xml | 18 +++++++-------- Habitica/res/values-nl/strings.tutorial.xml | 4 ++-- Habitica/res/values-nl/strings.xml | 18 +++++++-------- Habitica/res/values-ro/strings.xml | 2 +- Habitica/res/values-sv/strings.xml | 6 ++--- Habitica/res/values-zh/strings.xml | 2 +- Habitica/res/values/strings.tutorial.xml | 4 ++-- Habitica/res/values/strings.xml | 22 +++++++++---------- store_strings.xml | 2 +- translations/store_strings-cs.xml | 2 +- translations/store_strings-de.xml | 2 +- translations/store_strings-en-rGB.xml | 2 +- translations/store_strings-fil.xml | 2 +- translations/store_strings-id.xml | 2 +- translations/store_strings-it.xml | 2 +- translations/store_strings-ja.xml | 2 +- translations/store_strings-nl.xml | 2 +- 29 files changed, 98 insertions(+), 98 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 748221bb1..872075d54 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -162,7 +162,7 @@ android { multiDexEnabled true 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 2472 + versionCode 2475 versionName "2.7.1" } diff --git a/Habitica/res/layout/todo_item_card.xml b/Habitica/res/layout/todo_item_card.xml index b1b40ff9b..dde8814f9 100644 --- a/Habitica/res/layout/todo_item_card.xml +++ b/Habitica/res/layout/todo_item_card.xml @@ -59,7 +59,7 @@ android:textColor="#000" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:text="To-Do Title" /> + tools:text="To Do Title" /> Inviteret til Quest Værdi - Ny To-Do + Ny To Do Ny Belønning Ny Daglig Opgave Ny Vane @@ -136,7 +136,7 @@ Medlemmer Vaner Daglige - To-Dos + To Do\'s Belønninger Er du sikker? Vil du virkelig slette? @@ -302,10 +302,10 @@ Tilføj Opgave Tilføj Vane Tilføj Daglig Opgave - Tilføj To-Do + Tilføj To Do Tilføj Belønning Habitica Daglige Opgaver - Habitica To-Do Liste + Habitica To Do Liste Habitica Tilføj Opgave Køb @@ -334,7 +334,7 @@ Daglig Vane Belønning - To-Do + To Do Officiel Deltager Udfordring diff --git a/Habitica/res/values-de/strings.tutorial.xml b/Habitica/res/values-de/strings.tutorial.xml index 829e8e7e1..2025c4a05 100644 --- a/Habitica/res/values-de/strings.tutorial.xml +++ b/Habitica/res/values-de/strings.tutorial.xml @@ -7,8 +7,8 @@ Probier es aus! Du kannst die anderen Aufgaben-Typen kennenernen, indem du die untere Navigation benutzt. Erstelle tägliche Aufgaben für zeitkritische Aufgaben, die regelmäßig erledigt werden müssen. Pass auf - wenn Du eine dieser Aufgaben nicht erledigst, wird Deinem Avatar über Nacht Schaden zugefügt. Erledige Deine Aufgaben täglich und Du wirst tolle Belohnungen erhalten! - Nutze die To-Dos, um Aufgaben zu organisieren, die du nur einmalig erledigen musst. - Falls Dein To-Do an einem bestimmten Tag erledigt sein muss, kannst du dafür ein Fälligkeitsdatum erstellen. Es sieht so aus, als ob du jetzt auch eine Aufgabe abhaken kannst - probier es aus! + Nutze die To Do\'s, um Aufgaben zu organisieren, die du nur einmalig erledigen musst. + Falls Dein To Do an einem bestimmten Tag erledigt sein muss, kannst du dafür ein Fälligkeitsdatum erstellen. Es sieht so aus, als ob du jetzt auch eine Aufgabe abhaken kannst - probier es aus! Kaufe dir mit dem verdienten Gold Ausrüstung für deinen Avatar! Du kannst auch benutzerdefinierte Belohnungen erstellen, die sich auf etwas in Deinem wirklichen Leben beziehen, je nachdem was Dich motiviert. Das war\'s für das Erste. Falls du eine Erinnerungshilfe brauchst, dann schau in die FAQs. diff --git a/Habitica/res/values-de/strings.xml b/Habitica/res/values-de/strings.xml index 897543a21..916ddc6bf 100644 --- a/Habitica/res/values-de/strings.xml +++ b/Habitica/res/values-de/strings.xml @@ -106,7 +106,7 @@ Mitglieder Gewohnheiten Tagesaufgaben - To-Dos + To Do\'s Belohnungen Ja Nein @@ -305,12 +305,12 @@ Neue Aufgabe hinzufügen Neue Gewohnheit hinzufügen Neue Tagesaufgabe hinzufügen - Neues To-Do hinzufügen + Neues To Do hinzufügen Neue Belohnung hinzufügen Du hast alle Deine Tagesaufgaben erledigt. Gut gemacht! Habitica: Gewohnheit Habitica: Tagesaufgaben - Habitica To-Do-Liste + Habitica To Do-Liste Google Play Dienste konnten nicht gefunden werden. Kaufen Das Erwerben von Edelsteinen unterstützt die Entwickler und hilft Habitica am Laufen zu halten @@ -344,7 +344,7 @@ Abonnieren Alexander der Händler wird Dir nun Edelsteine für jeweils 20 Goldmünzen pro Stück verkaufen.\n\nSeine monatlichen Lieferungen sind zunächst auf 25 Edelsteine pro Monat beschränkt, welche jedoch durch die Dauer Deines Abonnements erhöht werden.\n\nDas Limit steigt um 5 Edelsteine für jeweils drei durchgehend abonnierte Monate, bis zu einem Maximum von 50 Edelsteinen pro Monat! Jeden Monat wirst Du einen einzigartigen optischen Gegenstand für Deinen Avatar erhalten.\n\nAußerdem gewährt Dir der Mysteriöse Zeitreisende für jeweils drei durchgehend abonnierte Monate Zugang zu historischen (und futuristischen!) optischen Gegenständen. - Verlängert die Historie erledigter To-Dos und Aufgaben. + Verlängert die Historie erledigter To Do\'s und Aufgaben. Verdoppelte Beute-Limits ermöglichen es Dir, täglich von erledigten Aufgaben mehr Gegenstände zu finden und deinen Stall schneller zu vervollständigen! +%d Mystische Sanduhr Zahlungsmethode @@ -378,7 +378,7 @@ Tagesaufgabe Gewohnheit Belohnung - To-Do + To Do Offiziell Herausforderung Du nimmst im Moment an keiner Herausforderung teil! @@ -426,8 +426,8 @@ Gewohnheiten sind Aufgaben ohne festen Zeitplan. Du kannst sie mehrmals am Tag oder gar nicht abhaken. Du hast keine Tagesaufgaben Tagesaufgaben sind sich regelmäßig wiederholende Aufgaben. Such Dir den Zeitplan aus, der Dir am besten passt! - Du hast keine To-Dos - To-Dos sind Aufgaben, die nur einmal abgehakt werden. Füge Unteraufgaben zu den To-Dos hinzu, um deren Wert zu steigern. + Du hast keine To Do\'s + To Do\'s sind Aufgaben, die nur einmal abgehakt werden. Füge Unteraufgaben zu den To Do\'s hinzu, um deren Wert zu steigern. Du hast keine Belohnungen Setze Justins Einführung zurück Bitte lies Dir unsere Community-Richtlinien durch, bevor du etwas postest @@ -620,7 +620,7 @@ Die Quest-Schriftrolle wird an den Quest-Besitzer zurückgegeben. Hast Du Deine Aufgaben heute abgehakt\? Es gibt eine Menge freizuschalten und zu entdecken während Du in den Leveln aufsteigst, also bleib an Deinen Aufgaben dran und hab Spaß! Willst Du etwas Neues ausprobieren\? Tritt einer Herausforderung bei um Deine Aufgabenliste zu erweitern und ein paar Edelsteine zu gewinnen! - Erweitere Deine To-Dos mit Kontrolllisten um Deine Belohnungen zu vervielfachen! + Erweitere Deine To Do\'s mit Kontrolllisten um Deine Belohnungen zu vervielfachen! Du kannst verändern wie oft sich eine Tagesaufgabe wiederholt. Sogar gelegentliche Aufgaben können festgelegt werden. Du kannst auch Erinnerungen für Deine Tagesaufgaben einplanen. Deine Aufgaben hin und wieder zu überdenken hilft Dir auf dem richtigen Weg zu bleiben. @@ -643,7 +643,7 @@ Die Quest-Schriftrolle wird an den Quest-Besitzer zurückgegeben. Wie sollen wir Dich nennen? Anzeigenamen müssen zwischen 1 und 30 Zeichen lang sein Tritt Habitica bei (Hak mich ab!) - Du kannst dieses To-Do erledigen, bearbeiten oder entfernen. + Du kannst dieses To Do erledigen, bearbeiten oder entfernen. Belohne Dich Schau Fernsehen, spiel ein Spiel, iss etwas Süßes, es liegt ganz an Dir! Internetseite besuchen diff --git a/Habitica/res/values-en-rGB/strings.tutorial.xml b/Habitica/res/values-en-rGB/strings.tutorial.xml index 6a115f2c0..9745f2f18 100644 --- a/Habitica/res/values-en-rGB/strings.tutorial.xml +++ b/Habitica/res/values-en-rGB/strings.tutorial.xml @@ -7,8 +7,8 @@ Give it a shot! You can explore the other task types through the bottom navigation. Make Dailies for time sensitive tasks that need to be done on a regular schedule. Be careful — if you miss one, your avatar will take damage overnight. Checking them off consistently brings great rewards! - Use To-dos to keep track of tasks you need to do just once. - If your To-do has to be done by a certain time, set a due date. Looks like you can check one off — go ahead! + Use To Do\'s to keep track of tasks you need to do just once. + If your To Do has to be done by a certain time, set a due date. Looks like you can check one off — go ahead! Buy gear for your avatar with the gold you earn! You can also make real-world Custom Rewards based on what motivates you. That\'s all for now. If you need a reminder, check the FAQ section. diff --git a/Habitica/res/values-en-rGB/strings.xml b/Habitica/res/values-en-rGB/strings.xml index c680e7a27..e5f2272a6 100644 --- a/Habitica/res/values-en-rGB/strings.xml +++ b/Habitica/res/values-en-rGB/strings.xml @@ -102,7 +102,7 @@ Members Habits Dailies - To-Dos + To Do\'s Rewards Yes No @@ -280,12 +280,12 @@ Add Task Add Habit Add Daily - Add To-Do + Add To Do Add Reward You completed all your dailies. Well done! Habitica Do Habit Habitica Dailies - Habitica To-Do List + Habitica To Do List Google Play services could not be found. Purchase Buying gems supports the developers and helps keep Habitica running @@ -318,7 +318,7 @@ Subscribe Alexander the Merchant will now sell you gems for 20 gold each!\n\nHis monthly shipments are initially capped at 25 Gems per month, but can increase based on your subscription length.\n\nThe cap increases by 5 Gems for every three months of consecutive subscription, up to a maximum of 50 Gems per month! Each month you will receive a unique cosmetic item for your avatar!\n\nPlus, for every three months of consecutive subscription, the Mysterious Time Travellers will grant you access to historic (and futuristic!) cosmetic items. - Makes completed To-Dos and task history available for longer. + Makes completed To Do\'s and task history available for longer. Double drop caps will let you receive more items from your completed tasks every day, helping you complete your stable faster! +%d Mystic Hourglass Payment method @@ -351,7 +351,7 @@ Daily Habit Reward - To-Do + To Do Official Challenge You’re not part of any Challenges right now! @@ -394,8 +394,8 @@ Habits are tasks that don&rsquo;t have a rigid schedule. You can check them off many times a day, or not at all. You don&rsquo;t have any Dailies Dailies are tasks that repeat on a regular basis. Choose the schedule that works for you! - You don&rsquo;t have any To-Dos - To-Dos are tasks that only need to be completed once. Add checklists to your To-Dos to increase their value. + You don&rsquo;t have any To Do\'s + To Do\'s are tasks that only need to be completed once. Add checklists to your To Do\'s to increase their value. You don&rsquo;t have any Rewards Reset Justin&rsquo;s Walkthrough Please read our Community Guidelines before posting @@ -622,7 +622,7 @@ Did you check off your tasks today\? There\'s lots to unlock and discover as you level up, so keep up with your tasks and have fun! Want to try something new\? Join a Challenge to expand your task list and win some Gems! - Add checklists to your To-Dos to multiply your rewards! + Add checklists to your To Do\'s to multiply your rewards! You can change how often each Daily repeats. Even infrequent tasks can be schedulled. You can schedule specific reminders for Dailies too. Occasionally re-evaluating your tasks can help keep you on the right path. @@ -657,7 +657,7 @@ What should we call you\? Display names must be between 1 and 30 characters Join Habitica (Check me off!) - You can either complete this To-Do, edit it, or remove it. + You can either complete this To Do, edit it, or remove it. Reward yourself Watch TV, play a game, eat a treat, it’s up to you! STR: diff --git a/Habitica/res/values-in/strings.tutorial.xml b/Habitica/res/values-in/strings.tutorial.xml index 9624db2fa..da5d2aa6e 100644 --- a/Habitica/res/values-in/strings.tutorial.xml +++ b/Habitica/res/values-in/strings.tutorial.xml @@ -7,8 +7,8 @@ Coba deh! Kamu bisa mengeksplor macam-macam tugas lain melalui tombol navigasi di bawah. Buat Keseharian untuk tugas-tugas yang terikat waktu dan butuh untuk diselesaikan secara berkala. Hati-hati — kalau ada yang terlewat, avatar kamu akan terkena damage besoknya. Menyelesaikan Keseharian secara konsisten memberi banyak keuntungan! - Gunakan To-do untuk mencatat tugas-tugas yang hanya perlu kamu lakukan sekali. - Kalau To-do-mu harus diselesaikan pada waktu tertentu, tetapkan tenggat waktunya. Sepertinya ada satu yang bisa kamu centang sekarang — sana! + Gunakan To Do untuk mencatat tugas-tugas yang hanya perlu kamu lakukan sekali. + Kalau To Do-mu harus diselesaikan pada waktu tertentu, tetapkan tenggat waktunya. Sepertinya ada satu yang bisa kamu centang sekarang — sana! Beli perlengkapan untuk avatarmu menggunakan koin emas yang kamu dapatkan! Kamu juga bisa membuat Hadiah yang benar-benar ada di dunia nyata tergantung apa yang memotivasimu. Itu dulu untuk sekarang. Kalau kamu butuh pengingat, lihat bagian FAQ. diff --git a/Habitica/res/values-in/strings.xml b/Habitica/res/values-in/strings.xml index 827b3a8e7..5c7277a46 100644 --- a/Habitica/res/values-in/strings.xml +++ b/Habitica/res/values-in/strings.xml @@ -102,7 +102,7 @@ Anggota Kebiasaan Keseharian - To-Do + To Do Hadiah Ya Tidak @@ -296,7 +296,7 @@ Anda telah menyelesaikan semua keseharianmu. Selamat! Habitica Melakukan Kebiasaan Keseharian Habitica - Daftar To-Do Habitica + Daftar To Do Habitica Google play services tidak dapat ditemukan. Bayar Membeli gem dapat mendukung pengembang dan menjaga Habitica tetap berjalan @@ -329,7 +329,7 @@ Berlangganan Alexander sang Saudagar akan menjual permata kepadamu masing-masing seharga 20 koin emas!\n\nPengiriman bulanannya dibatasi di 25 Permata per bulan, tapi bisa meningkat berdasarkan lama berlangganan-mu. \n\nBatasnya meningkat sebanyak 5 Permata setiap tiga bulan berturut-turut kamu berlangganan, hingga batas maksimal 50 Permata per bulan! Setiap bulan kamu akan menerima sebuah item kosmetik unik untuk avatarmu!\n\nPlus, setiap tiga bulan berturut-turut kamu berlangganan, sang Penjelajah Waktu Misterius akan memberimu akses kepada item kosmetik bersejarah (atau futuristik!). - Buat To-Do yang telah diselesaikan dan riwayat tugas tersedia lebih lama. + Buat To Do yang telah diselesaikan dan riwayat tugas tersedia lebih lama. Dua kali lipat batas drop akan mengizinkanmu mendapat lebih banyak item untuk tugas yang terselesaikan setiap hari, membantumu melengkapi istalmu lebih cepat! +%d Jam Pasir Mistis Metode Pembayaran @@ -362,7 +362,7 @@ Keseharian Kebiasaan Hadiah - To-Do + To Do Resmi Tantangan Kamu tidak mengambil bagian dalam Tantangan apapun saat ini! @@ -407,8 +407,8 @@ Kebiasaan adalah tugas yang tidak memerlukan jadwal ketat. Kamu bisa menyelesaikannya beberapa kali sehari, atau tidak sama sekali. Kamu tidak punya Keseharian apapun Keseharian adalah tugas yang berulang setiap waktu tertentu secara teratur. Pilih jadwal yang bekerja untukmu! - Kamu tidak punya To-Do apapun - To-Do adalah tugas yang hanya perlu diselesaikan sekali. Tambahkan ceklis kepada To-Do-mu untuk meningkatkan harganya. + Kamu tidak punya To Do apapun + To Do adalah tugas yang hanya perlu diselesaikan sekali. Tambahkan ceklis kepada To Do-mu untuk meningkatkan harganya. Kamu tidak punya Hadiah apapun Ulang Panduan Justin Tolong baca Pedoman Komunitas kami sebelum posting diff --git a/Habitica/res/values-it/strings.tutorial.xml b/Habitica/res/values-it/strings.tutorial.xml index 787597fa7..0c364ede2 100644 --- a/Habitica/res/values-it/strings.tutorial.xml +++ b/Habitica/res/values-it/strings.tutorial.xml @@ -7,8 +7,8 @@ Ora provaci tu! Puoi trovare altri tipi di attività usando la barra di navigazione in basso. Crea Daily per attività che devono essere svolte periodicamente. Sta attento - se ne salti una il tuo avatar subirà dei danni durante la notte. Completale con regolarità e otterrai grandi premi! - Usa le To-do per tenere traccia delle cose che devi fare soltanto una volta. - Se le tue To-do devono essere completate entro un certo giorno, imposta una data di scadenza. Pare che tu possa completarne una, prova! + Usa le To Do per tenere traccia delle cose che devi fare soltanto una volta. + Se le tue To Do devono essere completate entro un certo giorno, imposta una data di scadenza. Pare che tu possa completarne una, prova! Compra oggetti per il tuo avatar con l\'oro che ottieni! Puoi anche creare delle ricompense reali, basate su ciò che ti motiva. Per ora è tutto. Se hai bisogno di un ripasso, consulta la sezione FAQ. diff --git a/Habitica/res/values-it/strings.xml b/Habitica/res/values-it/strings.xml index d4b0684ec..b54de3ce2 100644 --- a/Habitica/res/values-it/strings.xml +++ b/Habitica/res/values-it/strings.xml @@ -106,7 +106,7 @@ Membri Abitudini Daily - To-do + To Do Ricompense No @@ -305,12 +305,12 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Aggiungi Attività Aggiungi Abitudine Aggiungi Daily - Aggiungi To-Do + Aggiungi To Do Aggiungi Ricompensa Hai completato tutte le tue Daily. Ottimo lavoro! Habitica esegui Abitudine Habitica Daily - Habitica lista To-Do + Habitica lista To Do Impossibile trovare Google Play Services. Compra Comprando gemme supporti gli sviluppatori e tieni in vita Habitica @@ -344,7 +344,7 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Abbonati Ora Alexander il Mercante ti venderà Gemme al prezzo di 20 Oro l\'una!\n\nLe sue consegne mensili sono inizialmente limitate a 25 Gemme al mese, ma possono aumentare a seconda della durata del tuo abbonamento.\n\nIl limite aumenta di 5 Gemme ogni tre mesi di abbonamento consecutivi, fino ad un massimo di 50 Gemme al mese! Ogni mese riceverai un oggetto davvero unico per il tuo avatar!\n\nIn più, ogni tre mesi di abbonamento consecutivi, i misteriosi Viaggiatori del Tempo ti permetteranno di ottenere oggetti antichi (e futuri!). - Rende le To-Do completate e la cronologia dei progressi delle attività disponibili più a lungo. + Rende le To Do completate e la cronologia dei progressi delle attività disponibili più a lungo. Raddoppiare il numero massimo di drop giornalieri ti farà ricevere più oggetti dalle attività completate ogni giorno, aiutandoti a completare la tua scuderia più velocemente! Limite di 25 Gemme Limite di 30 Gemme @@ -382,7 +382,7 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Daily Abitudine Ricompensa - To-Do + To Do Ufficiale Sfida Al momento non stai partecipando a nessuna sfida! @@ -428,8 +428,8 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Le Abitudini sono attività che possono essere svolte in modo molto flessibile. Puoi usarle diverse volte al giorno, o non usarle affatto. Non hai nessuna Daily Le Daily sono delle attività che vanno svolte regolarmente. Scegli la frequenza con cui ti trovi meglio! - Non hai alcuna To-do. - Le To-do sono attività da completare solo una volta. Aggiungi una checklist alle tue To-do per aumentarne il valore. + Non hai alcuna To Do. + Le To Do sono attività da completare solo una volta. Aggiungi una checklist alle tue To Do per aumentarne il valore. Non hai nessuna Ricompensa Ripristina la spiegazione introduttiva di Justin Per favore, leggi le Linee guida della community prima di scrivere un post. @@ -617,7 +617,7 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Hai completato le tue attività oggi? Sbloccherai e scoprirai cose nuove man mano che salirai di livello, quindi continua a completare le tue attività e divertiti! Vuoi provare qualcosa di nuovo? Unisciti ad una Sfida per espandere la tua lista delle attività e vincere qualche Gemma! - Aggiungi delle checklist alle tue To-Do perché le tue ricompense si moltiplichino! + Aggiungi delle checklist alle tue To Do perché le tue ricompense si moltiplichino! Puoi regolare la frequenza di ripetizione di ogni Daily. Perfino la data delle attività infrequenti può essere programmata. Puoi impostare dei promemoria specifici anche per le Daily. Rivalutare occasionalmente le tue attività può aiutarti a mantenere la giusta strada. @@ -653,7 +653,7 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Come dovremmo chiamarti? Il nome pubblico dev\'essere tra 1 e 30 caratteri. Raggiungi Habitica (spunta questa casella!) - Puoi completare questa To-Do, modificarla, o rimuoverla. + Puoi completare questa To Do, modificarla, o rimuoverla. Premiati Guarda la TV, divertiti con un videogioco, mangia un dolcetto, a te la scelta! FOR: @@ -708,7 +708,7 @@ Le Dailies mancate e le cattive Abitudini non li danneggiano molto, e hanno semp Riepilogo della Gilda O cancellala dalla schermata di modifica Clicca qui per modificarla in una cattiva abitudine che vorresti perdere - Può essere un\'Abitudine, una Daily o una To-Do + Può essere un\'Abitudine, una Daily o una To Do Aggiungi un\'attività su Habitica Costo Ti sei unito alla Gilda diff --git a/Habitica/res/values-ja/strings.tutorial.xml b/Habitica/res/values-ja/strings.tutorial.xml index 4a65497a9..2eaf48580 100644 --- a/Habitica/res/values-ja/strings.tutorial.xml +++ b/Habitica/res/values-ja/strings.tutorial.xml @@ -7,8 +7,8 @@ 挑戦してみよう!下のほうのナビゲーションから、異なるタスクタイプも選ぶことができます。 通常のスケジュールにしたがって行うべき期限付きのタスクは、日課に設定しましょう。 気をつけて…もし一つでもやり逃すと、あなたのアバターは夜のうちにダメージを受けてしまいます。継続的にチェックを入れることで、素晴らしい報酬を手に入れましょう! - 単発のタスクをこなすために、To-Doを使いましょう。 - もしTo-Doに期限があるのなら、設定しましょう。あなたにはクリアできるはず…がんばって! + 単発のタスクをこなすために、To Doを使いましょう。 + もしTo Doに期限があるのなら、設定しましょう。あなたにはクリアできるはず…がんばって! 得られたゴールドであなたのアバター用に装備を購入しましょう! あなた自身のモチベーションを上げるために、現実世界での報酬を登録することもできます。 これで説明は終わり。もし忘れちゃったときは,FAQをチェックしてみてね。 diff --git a/Habitica/res/values-ja/strings.xml b/Habitica/res/values-ja/strings.xml index 85e5d4b0f..5134148c8 100644 --- a/Habitica/res/values-ja/strings.xml +++ b/Habitica/res/values-ja/strings.xml @@ -106,7 +106,7 @@ メンバー 習慣 日課 - To-Do + To Do ごほうび はい いいえ @@ -304,12 +304,12 @@ タスクを追加 習慣を追加 日課を追加 - To-Do を追加 + To Do を追加 ごほうびを追加 日課をすべて完了した。お見事! Habitica の習慣 Habitica の日課 - Habitica のTo-Do リスト + Habitica のTo Do リスト Google Play サービスが見つかりません。 購入 ジェムを購入することで、開発者を支援し、Habitica の運営を維持する手助けができます @@ -348,7 +348,7 @@ 毎月、アバターを個性的に装飾するアイテムが手に入ります! \n \nさらに寄付の継続3カ月ごとに、謎のタイムトラベラーによって、歴史的(そして未来的!)な装飾アイテムが入手可能になります。 - 完了した To-Do やタスクの履歴を、より長期間閲覧可能になります。 + 完了した To Do やタスクの履歴を、より長期間閲覧可能になります。 落とし物の上限が2倍になり、毎日の完了したタスクから、より多くのアイテムを獲得することができます。動物小屋のコンプリートも早くなります! 上限 25 ジェム 上限 30 ジェム @@ -385,7 +385,7 @@ 日課 習慣 ごほうび - To-Do + To Do Habitica公式 チャレンジ 今参加しているチャレンジはありません! @@ -433,8 +433,8 @@ 習慣は、タスクの中でもこなすスケジュールがきっちりと決まっていないもの。1日に何回チェックしてもいいし、チェックしない日があっても大丈夫。 日課を持っていません 日課は一定のペースでこなすタスクだよ。自分に合ったスケジュールを組もう! - To-Doがありません - To-Doは一度だけ実行すればいいタスク。チェックリストを加えて忘れないようにしよう。 + To Doがありません + To Doは一度だけ実行すればいいタスク。チェックリストを加えて忘れないようにしよう。 ごほうびがありません チュートリアルをリセット 投稿する前に、私たちのコミュニティガイドラインを見直してください @@ -625,7 +625,7 @@ 今日のタスクはチェックしましたか? あなたがレベルアップするとアンロックされたり発見したりできるものがたくさんあります。だからタスクへ取り組み続けて、楽しんでいきましょう! 何か新しいことに挑戦したいですか? あなたのタスクリストを発展させてくれるチャレンジに参加して、いくつかのジェムを獲得しましょう! - 報酬を増やすためにTo-Doにチェックリストを加えてみましょう! + 報酬を増やすためにTo Doにチェックリストを加えてみましょう! それぞれの日課をどのくらいの頻度で繰り返すかを変更することができます。たまにしなかないタスクでさえスケジュールすることができます。 日課に対して特定のリマインダーを設定することもできます。 ときどきタスクを見直して再評価することは、正しい道筋を進み続けるために役立ちます。 @@ -660,7 +660,7 @@ あなたを何と呼べばいいですか? 表示名は1~30文字以内にしてください Habiticaに参加する(チェックして!) - To-Doは完了したり、編集したり、削除することができます。 + To Doは完了したり、編集したり、削除することができます。 自分自身へごほうびを与える TVを見ましょう、ゲームで遊びましょう、おやつを食べましょう、あなた次第です! 力: diff --git a/Habitica/res/values-nl/strings.tutorial.xml b/Habitica/res/values-nl/strings.tutorial.xml index 00166cd28..a85bd493b 100644 --- a/Habitica/res/values-nl/strings.tutorial.xml +++ b/Habitica/res/values-nl/strings.tutorial.xml @@ -7,8 +7,8 @@ Probeer het maar! Je kan de andere soorten taken doornemen met de onderstaande navigatie. Maak dagelijkse taken voor tijdgevoelige taken die volgens een vast schema gedaan moeten worden. Wees voorzichtig - als je er een mist, verliest je avatar gezondheid de volgende dag. Vink ze regelmatig af voor grootse beloningen! - Gebruik to-do\'s om taken bij te houden die je slechts één keer moet doen. - Als je to-do tegen een bepaalde dag afgewerkt moet zijn, voer dan een einddatum in. Je kan er een afvinken - doe maar! + Gebruik To Do\'s om taken bij te houden die je slechts één keer moet doen. + Als je To Do tegen een bepaalde dag afgewerkt moet zijn, voer dan een einddatum in. Je kan er een afvinken - doe maar! Koop een uitrusting voor je avatar met het goud dat je verdient! Je kan ook zelf beloningen maken voor in de echte wereld, gebaseerd op wat je motiveert. Dat was het voorlopig. Als je iets vergeet, kijk dan in de FAQ sectie. diff --git a/Habitica/res/values-nl/strings.xml b/Habitica/res/values-nl/strings.xml index b8e0e58ca..3572a6f8d 100644 --- a/Habitica/res/values-nl/strings.xml +++ b/Habitica/res/values-nl/strings.xml @@ -106,7 +106,7 @@ Leden Gewoontes Dagelijkse taken - To-do\'s + To Do\'s Beloningen Ja Nee @@ -304,12 +304,12 @@ Voeg taak toe Voeg Gewoonte toe Voeg Dagelijkse taak toe - Voeg To-do toe + Voeg To Do toe Voeg Beloning toe Je hebt al je Dagelijkse taken voltooid. Goed gedaan! Habitica Doe Gewoonte Habitica Dagelijkse taken - Habitica to-do lijst + Habitica To Do lijst Google play diensten niet gevonden. Kopen Door het kopen van edelstenen steun je de ontwikkelaars en help je Habitica online te houden @@ -343,7 +343,7 @@ Abonneer Alexander de Koopman zal nu edelstenen aan je verkopen voor 20 goud per edelsteen!\n\nZijn maandelijkse levering is initieel beperkt tot 25 edelstenen per maand, maar stijgt afhankelijk van de duur van je abonnement.\n\nDit limiet verhoogt met 5 edelstenen voor elke 3 maanden van opeenvolgende abonnement periodes, tot een maximum van 50 edelstenen per maand! Iedere maand ontvang je een uniek cosmetisch voorwerp voor je avatar!\n\nEn voor iedere 3 maanden van opeenvolgende abonnementsperiodes, geven de mysterieuze tijdreizigers je toegang tot historische (en futuristische!) cosmetische voorwerpen. - Maakt voltooide To-do\'s en taakgeschiedenis langer beschikbaar. + Maakt voltooide To Do\'s en taakgeschiedenis langer beschikbaar. Dubbele vondstlimieten laten je dagelijks meer voorwerpen verdienen van je voltooide taken, waardoor je je stal sneller kan voltooien! 25 Edelsteen drempel 30 Edelsteen drempel @@ -381,7 +381,7 @@ Dagelijkse taak Gewoonte Beloning - To-do + To Do Officieel Uitdaging Je maakt geen deel uit van uitdagingen op dit moment! @@ -426,8 +426,8 @@ Gewoontes zijn taken die geen vast schema hebben. Je kan ze meerdere keren per dag afvinken of helemaal niet. Je hebt geen dagelijkse taken Dagelijkse taken zijn taken die op een vast schema herhalen. Kies de routine die voor jou werkt! - Je hebt geen to-do\'s - To-do\'s zijn taken die slechts een keer voltooid moeten worden. Voeg checklijsten aan je to-do\'s toe om hun waarde te verhogen. + Je hebt geen To Do\'s + To Do\'s zijn taken die slechts een keer voltooid moeten worden. Voeg checklijsten aan je To Do\'s toe om hun waarde te verhogen. Je hebt geen beloningen Herstart Justins inleiding Lees alsjeblieft onze gemeenschapsrichtlijnen voordat je berichten plaatst @@ -615,7 +615,7 @@ Heb je jou taken afgevinkt vandaag? Er is veel om te ontgrendelen en te ontdekken als je niveau omhoog gaat, dus houd je taken bij en veel plezier! Wil je iets nieuws proberen? Sluit je aan bij een uitdaging om je takenlijst te vergroten en win wat Edelstenen! - Voeg checklijsten toe aan jou To-Dos om de beloningen te vermenigvuldigen! + Voeg checklijsten toe aan jou To Do\'s om de beloningen te vermenigvuldigen! Je kunt veranderen hoe vaak een Dagelijkse taak zich herhaalt. Zelfs onregelmatige taken kunnen ingepland worden. Je kunt ook specifieke herinneringen voor Dagelijkse taken inplannen. Het van tijd tot tijd herevalueren van je taken kan je helpen om op het rechte pad te blijven. @@ -643,7 +643,7 @@ Gebruikersnaam gekopieerd naar het prikbord Gebruikersnamen moeten tussen 1 en 30 karakters lang zijn Sluit je aan bij Habitica (Aanvinken) - Je kan deze To-do voltooien, bewerken of verwijderen + Je kan deze To Do voltooien, bewerken of verwijderen Beloon jezelf Kijk TV, speel een spel, eet een belonging, aan jou de keuze! KRA: diff --git a/Habitica/res/values-ro/strings.xml b/Habitica/res/values-ro/strings.xml index 745465d84..211d3921f 100755 --- a/Habitica/res/values-ro/strings.xml +++ b/Habitica/res/values-ro/strings.xml @@ -38,7 +38,7 @@ Invitat în Expediție Valoare - Nou To-Do + Nou To Do Răsplată noua Sarcină Zilnică Noua Obicei Nou diff --git a/Habitica/res/values-sv/strings.xml b/Habitica/res/values-sv/strings.xml index 78347ae35..1188c11b9 100755 --- a/Habitica/res/values-sv/strings.xml +++ b/Habitica/res/values-sv/strings.xml @@ -463,7 +463,7 @@ Daglig Vana Belöning - To-Do + To Do Officiell Deltar Utmaning @@ -517,8 +517,8 @@ Vanor är uppgifter som inte har något fast schema. Du kan klara dom flera gånger per dag, eller inga alls. Du har inga \"Dailies\" \"Dailies\" är uppgifter som upprepas på återkommande vis. Välj ett schema som passar dig! - Du har inga To-Do\'s - To-Do\'s är uppgifter som bara behöver göras en gång. Lägg till checklistor i dina To-Do\'s för att öka på värdet. + Du har inga To Do\'s + To Do\'s är uppgifter som bara behöver göras en gång. Lägg till checklistor i dina To Do\'s för att öka på värdet. Du har inga Belöningar Återställ Justins genomgång Snälla läs Gemenskapens Riktlinjer innan du du gör ett inlägg diff --git a/Habitica/res/values-zh/strings.xml b/Habitica/res/values-zh/strings.xml index 4470e0edd..3b8577b30 100644 --- a/Habitica/res/values-zh/strings.xml +++ b/Habitica/res/values-zh/strings.xml @@ -629,7 +629,7 @@ 分配点数的功能在10级解锁 你干的越多,奖励就会越多。溪流终将汇聚成大海。 想试试新东西?加入一个挑战来扩充你的人物列表并赢得一些宝石吧! - 把待办事项都加到你的To-Do列表来赢取奖励! + 把待办事项都加到你的To Do列表来赢取奖励! 你可以修改你的每日任务的重复频率。多罕见的任务都能被安排得明明白白。 你也可以安排特定的日程提醒。 深呼吸!保持专注!你能办到! diff --git a/Habitica/res/values/strings.tutorial.xml b/Habitica/res/values/strings.tutorial.xml index 42566a9d1..f1741fee0 100644 --- a/Habitica/res/values/strings.tutorial.xml +++ b/Habitica/res/values/strings.tutorial.xml @@ -7,8 +7,8 @@ Give it a shot! You can explore the other task types through the bottom navigation. Make Dailies for time sensitive tasks that need to be done on a regular schedule. Be careful — if you miss one, your avatar will take damage overnight. Checking them off consistently brings great rewards! - Use To-dos to keep track of tasks you need to do just once. - If your To-do has to be done by a certain time, set a due date. Looks like you can check one off — go ahead! + Use To Do\'s to keep track of tasks you need to do just once. + If your To Do has to be done by a certain time, set a due date. Looks like you can check one off — go ahead! Buy gear for your avatar with the gold you earn! You can also make real-world Custom Rewards based on what motivates you. That\'s all for now. If you need a reminder, check the FAQ section. diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 7e60c15a6..b0b582486 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -138,7 +138,7 @@ Members Habits Dailies - To-Do\'s + To Do\'s Rewards Yes No @@ -363,12 +363,12 @@ Add Task Add Habit Add Daily - Add To-Do + Add To Do Add Reward You completed all your dailies. Well done! Habitica Do Habit Habitica Dailies - Habitica To-Do List + Habitica To Do List Google play services could not be found. Purchase Buying gems supports the developers and helps keep Habitica running @@ -446,7 +446,7 @@ Daily Habit Reward - To-Do + To Do Official Challenge You’re not part of any Challenges right now! @@ -497,15 +497,15 @@ Habits are tasks that don\'t have a rigid schedule. You can check them off many times a day, or not at all. You don\'t have any Dailies Dailies are tasks that repeat on a regular basis. Choose the schedule that works for you! - You don\'t have any To-Do\'s - To-Do\'s are tasks that only need to be completed once. Add checklists to your To-Do\'s to increase their value. + You don\'t have any To Do\'s + To Do\'s are tasks that only need to be completed once. Add checklists to your To Do\'s to increase their value. You don\'t have any Rewards No Habits There aren\'t any Habits visible with your current filters. No Dailies There aren\'t any Dailies visible with your current filters. - No To-Do\'s - There aren\'t any To-Do\'s visible with your current filters. + No To Do\'s + There aren\'t any To Do\'s visible with your current filters. No Rewards Reset Tutorials Review our Community Guidelines before posting @@ -699,7 +699,7 @@ Did you check off your tasks today? There\'s lots to unlock and discover as you level up, so keep up with your tasks and have fun! Want to try something new? Join a Challenge to expand your task list and win some Gems! - Add checklists to your To-Do\'s to multiply your rewards! + Add checklists to your To Do\'s to multiply your rewards! You can change how often each Daily repeats. Even infrequent tasks can be scheduled. You can schedule specific reminders for Dailies too. Occasionally re-evaluating your tasks can help keep you on the right path. @@ -734,7 +734,7 @@ What should we call you? Display names must be between 1 and 30 characters Join Habitica (Check me off!) - You can either complete this To-Do, edit it, or remove it. + You can either complete this To Do, edit it, or remove it. Reward yourself Watch TV, play a game, eat a treat, it’s up to you! STR: @@ -817,7 +817,7 @@ You joined the guild Cost Add a task to Habitica - Either a Habit, a Daily or a To-Do + Either a Habit, a Daily or a To Do Tap here to edit this into a bad habit you\'d like to quit Or delete it from the edit screen Guild Summary diff --git a/store_strings.xml b/store_strings.xml index f7ed05bcf..bcc7a4957 100644 --- a/store_strings.xml +++ b/store_strings.xml @@ -3,7 +3,7 @@ Gamify Your Tasks Treat your life like a game to stay motivated and organized! Treat your life like a game to stay motivated and organized! Habitica makes it simple to have fun while accomplishing goals. -Input your Habits, your Daily goals, and your To-Do list, and then create a custom avatar. Check off tasks to level up your avatar and unlock features such as armor, pets, skills, and even quests! Fight monsters with friends to keep each other accountable, and use your gold on in-game rewards, like equipment, or custom awards, like watching an episode of your favorite TV show. Flexible, social, and fun, Habitica is the perfect way to motivate yourself to accomplish anything. +Input your Habits, your Daily goals, and your To Do list, and then create a custom avatar. Check off tasks to level up your avatar and unlock features such as armor, pets, skills, and even quests! Fight monsters with friends to keep each other accountable, and use your gold on in-game rewards, like equipment, or custom awards, like watching an episode of your favorite TV show. Flexible, social, and fun, Habitica is the perfect way to motivate yourself to accomplish anything. If you have any questions, feel free to send feedback to mobile@habitica.com! And if you enjoy our app, we would really appreciate it if you would leave us a review. diff --git a/translations/store_strings-cs.xml b/translations/store_strings-cs.xml index f9f1ded58..6e77e9578 100644 --- a/translations/store_strings-cs.xml +++ b/translations/store_strings-cs.xml @@ -3,7 +3,7 @@ Přeměň své úkoly na hru Berte život jako hru, načerpejte motivaci a mějte vše pod kontrolou! Ber svůj život jako hru, aby jsi zůstal motivovaný a organizovaný! S Habiticou je jednoduché si užívat zábavu a dokončovat své síle zároveň. -Zadej své zvyky, denní cíle a svůj to-do list a poté si vytvoř svou vlastní herní postavu. Odškrtávej si úkoly, aby jsi svou postavu dostal na další úroveň a odemkni si vymoženosti jako brnění, domácí mazlíčky, schopnosti a dokonce i úkoly! Bojuj s monstry společně s kamarády, abyste se navzájem podporovali a použij své zlato na herní odměny, jako je vybavení, nebo na vlastní odměny v reálném životě jako např. sledování episod svého oblíbené seriálu. Přizpůsobivá, společenská a zábavná, Habitica je dokonalým způsobem na to se motivovat k tomu dosáhnout čehokoliv. +Zadej své zvyky, denní cíle a svůj To Do list a poté si vytvoř svou vlastní herní postavu. Odškrtávej si úkoly, aby jsi svou postavu dostal na další úroveň a odemkni si vymoženosti jako brnění, domácí mazlíčky, schopnosti a dokonce i úkoly! Bojuj s monstry společně s kamarády, abyste se navzájem podporovali a použij své zlato na herní odměny, jako je vybavení, nebo na vlastní odměny v reálném životě jako např. sledování episod svého oblíbené seriálu. Přizpůsobivá, společenská a zábavná, Habitica je dokonalým způsobem na to se motivovat k tomu dosáhnout čehokoliv. Máš-li otázky, neboj se poslat zpětnou vazbu na email mobile@habitica.com. A jestli se ti naše aplikace líbí, opravdu bychom ocenili, kdyby jsi nám zanechal hodnocení. diff --git a/translations/store_strings-de.xml b/translations/store_strings-de.xml index 6c31ef553..5af7a741c 100644 --- a/translations/store_strings-de.xml +++ b/translations/store_strings-de.xml @@ -3,7 +3,7 @@ Erledige deine Aufgaben spielerisch Betrachte Dein Leben als ein Spiel, um motiviert und organisiert zu bleiben! Betrachte Dein Leben als ein Spiel, um motiviert und organisiert zu bleiben! Habitica macht es Dir einfach, Spaß dabei zu haben, Deine persönlichen Ziele zu erreichen. -Füge Deine Gewohnheiten, Deine täglichen Ziele und Deine To-Do-Liste hinzu und erstelle Deinen eigenen Avatar. Hake Deine Aufgaben ab, damit Dein Avatar auf ein höheres Level aufsteigen kann und um weitere Funktionen freizuschalten, wie beispielsweise Ausrüstung, Haustiere, Fähigkeiten und auch Quests! Du kannst Monster mit Deinen Freunden bekämpfen und euch so gegenseitig unterstützen. Du kannst Dein Gold dazu nutzen, um spielbezogene Belohnungen zu kaufen, oder für individuelle Belohnungen, wie beispielsweise eine Episode Deiner Lieblings-Fehrnsehserie zu gucken. Habitica ist flexibel, kommunikativ und macht Spaß, es bietet eine tolle Möglichkeit, Dich zu jedem Ziel zu motivieren. +Füge Deine Gewohnheiten, Deine täglichen Ziele und Deine To Do-Liste hinzu und erstelle Deinen eigenen Avatar. Hake Deine Aufgaben ab, damit Dein Avatar auf ein höheres Level aufsteigen kann und um weitere Funktionen freizuschalten, wie beispielsweise Ausrüstung, Haustiere, Fähigkeiten und auch Quests! Du kannst Monster mit Deinen Freunden bekämpfen und euch so gegenseitig unterstützen. Du kannst Dein Gold dazu nutzen, um spielbezogene Belohnungen zu kaufen, oder für individuelle Belohnungen, wie beispielsweise eine Episode Deiner Lieblings-Fehrnsehserie zu gucken. Habitica ist flexibel, kommunikativ und macht Spaß, es bietet eine tolle Möglichkeit, Dich zu jedem Ziel zu motivieren. Falls Du irgendwelche Fragen hast, kannst Du uns gerne Feedback an mobile@habitica.com schicken! Und falls Dir unsere App gefällt, würden wir uns freuen, wenn Du uns bewertest. diff --git a/translations/store_strings-en-rGB.xml b/translations/store_strings-en-rGB.xml index 947be27cc..e140fef18 100644 --- a/translations/store_strings-en-rGB.xml +++ b/translations/store_strings-en-rGB.xml @@ -3,7 +3,7 @@ Gamify Your Tasks Treat your life like a game to stay motivated and organised! Treat your life like a game to stay motivated and organised! Habitica makes it simple to have fun while accomplishing goals. -Input your Habits, your Daily goals, and your To-Do list, and then create a custom avatar. Check off tasks to level up your avatar and unlock features such as armour, pets, skills, and even quests! Fight monsters with friends to keep each other accountable, and use your gold on in-game rewards, like equipment, or custom awards, like watching an episode of your favourite TV show. Flexible, social, and fun, Habitica is the perfect way to motivate yourself to accomplish anything. +Input your Habits, your Daily goals, and your To Do list, and then create a custom avatar. Check off tasks to level up your avatar and unlock features such as armour, pets, skills, and even quests! Fight monsters with friends to keep each other accountable, and use your gold on in-game rewards, like equipment, or custom awards, like watching an episode of your favourite TV show. Flexible, social, and fun, Habitica is the perfect way to motivate yourself to accomplish anything. If you have any questions, feel free to send feedback to mobile@habitica.com! And if you enjoy our app, we would really appreciate it if you would leave us a review. diff --git a/translations/store_strings-fil.xml b/translations/store_strings-fil.xml index 23bd41c6e..b305530db 100644 --- a/translations/store_strings-fil.xml +++ b/translations/store_strings-fil.xml @@ -2,5 +2,5 @@ Isipin mo na ang buhay mo ay isang laro para lalo kang nagaganyak at mas oranisado! Gamify ang iyong Buhay - Tratuhin ang iyong buhay tulad ng isang laro upang manatili motivated at nakaayos! Ginagawang simple ng Habitica na magkaroon ng kasiyahan habang nagagawa ang mga layunin. Ipasok ang iyong Mga gawi, ang iyong Araw-araw na mga layunin, at ang iyong listahan ng To-Do, at pagkatapos ay lumikha ng isang pasadyang avatar. Suriin ang mga gawain sa antas ng iyong avatar at i-unlock ang mga tampok tulad ng armor, mga alagang hayop, kasanayan, at kahit quests! Labanan ang mga monsters sa mga kaibigan upang panatilihing may pananagutan ang isa\'t isa, at gamitin ang iyong ginto sa mga in-game na premyo, tulad ng kagamitan, o pasadyang mga parangal, tulad ng panonood ng isang episode ng iyong paboritong palabas sa TV. Flexible, social, at masaya, Habitica ay ang perpektong paraan upang mag-udyok sa iyong sarili upang makamit ang anumang bagay. Kung mayroon kang anumang mga katanungan, huwag mag-atubiling magpadala ng feedback sa mobile@habitica.com! At kung masiyahan ka sa aming app, talagang pinahahalagahan namin ito kung aalisin mo sa amin ang isang pagsusuri. + Tratuhin ang iyong buhay tulad ng isang laro upang manatili motivated at nakaayos! Ginagawang simple ng Habitica na magkaroon ng kasiyahan habang nagagawa ang mga layunin. Ipasok ang iyong Mga gawi, ang iyong Araw-araw na mga layunin, at ang iyong listahan ng To Do, at pagkatapos ay lumikha ng isang pasadyang avatar. Suriin ang mga gawain sa antas ng iyong avatar at i-unlock ang mga tampok tulad ng armor, mga alagang hayop, kasanayan, at kahit quests! Labanan ang mga monsters sa mga kaibigan upang panatilihing may pananagutan ang isa\'t isa, at gamitin ang iyong ginto sa mga in-game na premyo, tulad ng kagamitan, o pasadyang mga parangal, tulad ng panonood ng isang episode ng iyong paboritong palabas sa TV. Flexible, social, at masaya, Habitica ay ang perpektong paraan upang mag-udyok sa iyong sarili upang makamit ang anumang bagay. Kung mayroon kang anumang mga katanungan, huwag mag-atubiling magpadala ng feedback sa mobile@habitica.com! At kung masiyahan ka sa aming app, talagang pinahahalagahan namin ito kung aalisin mo sa amin ang isang pagsusuri. diff --git a/translations/store_strings-id.xml b/translations/store_strings-id.xml index 3f1c6c258..205455234 100644 --- a/translations/store_strings-id.xml +++ b/translations/store_strings-id.xml @@ -3,7 +3,7 @@ Buat Tugasmu Menjadi Game Perlakukan hidupmu seperti permainan untuk tetap termotivasi dan terorganisir! Perlakukan hidupmu seperti permainan agar tetap termotivasi dan terorganisir! Habitica membantumu untuk bersenang-senang dalam mencapai tujuan. -Masukkan Kebiasaan, sasaran Harian dan To-Do kamu, lalu buat avatarmu sendiri. Centang tugas-tugas untuk naik level dan buka fitur-fitur seperti baju, peliharaan, kemampuan, dan bahkan misi! Bertarung dengan monster bersama teman-teman supaya saling menyemangati, dan gunakan koin emas yang kamu punya untuk membeli hadiah di dalam game, seperti perlengkapan perang, atau hadiah yang kamu buat sendiri, misalnya menonton satu episode siaran TV kesukaanmu. Fleksibel, sosial, menyenangkan, Habitica sempurna untuk memotivasimu mencapai apapun. +Masukkan Kebiasaan, sasaran Harian dan To Do kamu, lalu buat avatarmu sendiri. Centang tugas-tugas untuk naik level dan buka fitur-fitur seperti baju, peliharaan, kemampuan, dan bahkan misi! Bertarung dengan monster bersama teman-teman supaya saling menyemangati, dan gunakan koin emas yang kamu punya untuk membeli hadiah di dalam game, seperti perlengkapan perang, atau hadiah yang kamu buat sendiri, misalnya menonton satu episode siaran TV kesukaanmu. Fleksibel, sosial, menyenangkan, Habitica sempurna untuk memotivasimu mencapai apapun. Kalau kamu punya pertanyaan maupun saran, silakan kirim ke mobile@habitica.com! Dan jika kamu menyukai aplikasi kami, kami akan sangat menghargai ulasanmu. diff --git a/translations/store_strings-it.xml b/translations/store_strings-it.xml index 520543eb4..5eb274833 100644 --- a/translations/store_strings-it.xml +++ b/translations/store_strings-it.xml @@ -4,7 +4,7 @@ Trasforma la tua vita in un gioco di ruolo per affrontarla motivato ed organizzato. Considera la tua vita come un gioco di ruolo per rimanere motivato e organizzato! Habitica la semplifica e ti fa divertire mentre raggiungi i tuoi obiettivi. -Inserisci le tue Abitudini, i tuoi obiettivi giornalieri (Daily) e la tua lista di cose da fare (To-Do), poi crea il tuo avatar personalizzato. Completa le attività per far salire di livello il tuo avatar e sbloccare funzionalità come armature, animali, abilità e persino missioni! Combatti i mostri con i tuoi amici per aiutarvi a vicenda ad essere responsabili, e usa il tuo oro per ricompense in-game come pezzi di equipaggiamento, o ricompense personalizzate, ad esempio guardare un episodio della tua serie TV preferita. Flessibile, sociale e soprattutto divertente, Habitica è il modo perfetto per motivarti a fare qualsiasi cosa. +Inserisci le tue Abitudini, i tuoi obiettivi giornalieri (Daily) e la tua lista di cose da fare (To Do), poi crea il tuo avatar personalizzato. Completa le attività per far salire di livello il tuo avatar e sbloccare funzionalità come armature, animali, abilità e persino missioni! Combatti i mostri con i tuoi amici per aiutarvi a vicenda ad essere responsabili, e usa il tuo oro per ricompense in-game come pezzi di equipaggiamento, o ricompense personalizzate, ad esempio guardare un episodio della tua serie TV preferita. Flessibile, sociale e soprattutto divertente, Habitica è il modo perfetto per motivarti a fare qualsiasi cosa. Se avete una qualsiasi domanda o dei suggerimenti, sentitevi liberi di scrivere a mobile@habitica.com! E se vi piace la nostra app, saremmo davvero felici se ci lasciaste una recensione. diff --git a/translations/store_strings-ja.xml b/translations/store_strings-ja.xml index 6704e72e3..267eba120 100644 --- a/translations/store_strings-ja.xml +++ b/translations/store_strings-ja.xml @@ -4,7 +4,7 @@ 自分の人生をゲーム化して、やる気の維持とやるべきことの整理をしよう! 自分の人生をゲーム化して、やる気の維持とやるべきことの整理をしましょう!Habitica は目標達成を楽しく簡単にします。 -習慣、毎日の目標、そしてTo-Do の一覧を入力し、お好みのアバターをつくりましょう。タスクをこなして、レベルを上げていくと、防具、ペット、スキルやクエストなどの機能をアンロックしていくこともできます! 責任をもちながら友達といっしょにモンスターと戦い、ゲーム内でゴールドを稼いで、アバターの装備や、「好きなテレビ番組の 1 話分」などの自分好みのごほうびを買うこともできます。柔軟で、ソーシャルで、楽しい――Habitica は、あなたがご自身の目標を達成するのを励ますカンペキな方法です。 +習慣、毎日の目標、そしてTo Do の一覧を入力し、お好みのアバターをつくりましょう。タスクをこなして、レベルを上げていくと、防具、ペット、スキルやクエストなどの機能をアンロックしていくこともできます! 責任をもちながら友達といっしょにモンスターと戦い、ゲーム内でゴールドを稼いで、アバターの装備や、「好きなテレビ番組の 1 話分」などの自分好みのごほうびを買うこともできます。柔軟で、ソーシャルで、楽しい――Habitica は、あなたがご自身の目標を達成するのを励ますカンペキな方法です。 質問があったら、ぜひお気軽に mobile@habitica.com あてにフィードバックをお寄せください!そしてもしこのアプリをお楽しみいただけたなら、レビューを残していただけると、たいへんうれしいです。 diff --git a/translations/store_strings-nl.xml b/translations/store_strings-nl.xml index 519c008ba..4f73ca3e5 100644 --- a/translations/store_strings-nl.xml +++ b/translations/store_strings-nl.xml @@ -3,7 +3,7 @@ Maak van je taken een spel Behandel je leven alsof het een spel is en blijf gemotiveerd en georganiseerd! Behandel je leven als een spel om gemotiveerd en georganiseerd te blijven! Habitica houdt het simpel om plezier te maken terwijl je doelen bereikt. -Voer je gewoontes, dagelijkse taken en to-do\'s toe en maak dan een eigen avatar. Vink taken af om je avatar sterker te maken en functies vrij te spelen zoals uitrusting, huisdieren, vaardigheden en zelfs queesten! Vecht tegen monsters met vrienden om samen verantwoordelijk te blijven en gebruik je goud voor beloningen, zoals uitrusting of kies je eigen beloning, zoals een aflevering van je favoriete serie bekijken. Flexibel, sociaal en plezant, Habitica is de perfecte manier om jezelf te motiveren om alles te bereiken. +Voer je gewoontes, dagelijkse taken en To Do\'s toe en maak dan een eigen avatar. Vink taken af om je avatar sterker te maken en functies vrij te spelen zoals uitrusting, huisdieren, vaardigheden en zelfs queesten! Vecht tegen monsters met vrienden om samen verantwoordelijk te blijven en gebruik je goud voor beloningen, zoals uitrusting of kies je eigen beloning, zoals een aflevering van je favoriete serie bekijken. Flexibel, sociaal en plezant, Habitica is de perfecte manier om jezelf te motiveren om alles te bereiken. Als je vragen hebt kan je ze stellen bij mobile@habitica.com! En als je de app leuk vindt, waarderen we het als je ons een recensie nalaat. From 181ad69099bdd0b1bc1a6d2870f0488a6df2cb7b Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 17:36:58 +0200 Subject: [PATCH 10/32] Fix #1316 --- .../habitica/ui/views/tasks/form/TaskSchedulingControls.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt index 3e3828e49..131c6e958 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt @@ -172,7 +172,7 @@ class TaskSchedulingControls @JvmOverloads constructor( generateSummary() } monthlyRepeatWeeksButton.setOnClickListener { - weeksOfMonth = mutableListOf(startDateCalendar.get(Calendar.WEEK_OF_MONTH)) + weeksOfMonth = mutableListOf(startDateCalendar.get(Calendar.WEEK_OF_MONTH) - 1) daysOfMonth = null generateSummary() } From 0cff57c7148ce58439de7550eeb96c82a9f33676 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 17:37:06 +0200 Subject: [PATCH 11/32] Fix content being loaded too often --- Habitica/build.gradle | 2 +- .../habitica/data/implementation/ContentRepositoryImpl.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 872075d54..4a834acf2 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -64,7 +64,7 @@ dependencies { compileOnly 'com.github.pengrad:jdk9-deps:1.0' //App Compatibility and Material Design implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.1.0' + implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' // Emojis diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index 9060fbf18..88949f64a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -22,7 +22,7 @@ abstract class ContentRepositoryImpl(localRepository override fun retrieveContent(context: Context?, forced: Boolean): Flowable { val now = Date().time - return if (forced || now - this.lastContentSync > 3) { + return if (forced || now - this.lastContentSync > 300000) { lastContentSync = now apiClient.content.doOnNext { context?.let {context -> From 1d9345376c13327fcecf6fa6290500446ccdfc46 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 16 Jul 2020 17:43:51 +0200 Subject: [PATCH 12/32] cache API responses. Fixes #1313 --- .../android/habitica/data/implementation/ApiClientImpl.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt index cb2e9a9c0..ff647fe60 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt @@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.data.implementation import android.content.Context import com.amplitude.api.Amplitude +import com.facebook.FacebookSdk.getCacheDir import com.google.gson.JsonSyntaxException import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.HabiticaBaseApplication @@ -37,6 +38,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.BiFunction import io.reactivex.functions.Consumer import io.reactivex.schedulers.Schedulers +import okhttp3.Cache import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.logging.HttpLoggingInterceptor @@ -102,7 +104,12 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; val timeZone = calendar.timeZone val timezoneOffset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS) + val cacheSize: Long = 10 * 1024 * 1024 // 10 MB + + val cache = Cache(getCacheDir(), cacheSize) + val client = OkHttpClient.Builder() + .cache(cache) .addInterceptor(logging) .addNetworkInterceptor { chain -> val original = chain.request() From 0a282cb77611a093ae2f9c5ffa1d9094f60e81cc Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jul 2020 14:50:11 +0200 Subject: [PATCH 13/32] begin implementing improved pet screen --- Habitica/res/drawable-hdpi/pet_status_egg.png | Bin 0 -> 592 bytes .../res/drawable-hdpi/pet_status_potion.png | Bin 0 -> 459 bytes Habitica/res/drawable-mdpi/pet_status_egg.png | Bin 0 -> 415 bytes .../res/drawable-mdpi/pet_status_potion.png | Bin 0 -> 299 bytes .../res/drawable-xhdpi/pet_status_egg.png | Bin 0 -> 817 bytes .../res/drawable-xhdpi/pet_status_potion.png | Bin 0 -> 612 bytes .../res/drawable-xxhdpi/pet_status_egg.png | Bin 0 -> 1259 bytes .../res/drawable-xxhdpi/pet_status_potion.png | Bin 0 -> 869 bytes Habitica/res/layout/pet_detail_item.xml | 17 +++++++++++++++ .../inventory/PetDetailRecyclerAdapter.kt | 20 +++++++++++++++++- 10 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 Habitica/res/drawable-hdpi/pet_status_egg.png create mode 100644 Habitica/res/drawable-hdpi/pet_status_potion.png create mode 100644 Habitica/res/drawable-mdpi/pet_status_egg.png create mode 100644 Habitica/res/drawable-mdpi/pet_status_potion.png create mode 100644 Habitica/res/drawable-xhdpi/pet_status_egg.png create mode 100644 Habitica/res/drawable-xhdpi/pet_status_potion.png create mode 100644 Habitica/res/drawable-xxhdpi/pet_status_egg.png create mode 100644 Habitica/res/drawable-xxhdpi/pet_status_potion.png diff --git a/Habitica/res/drawable-hdpi/pet_status_egg.png b/Habitica/res/drawable-hdpi/pet_status_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..5dd39f87de8adf45afa3da1d92cb42f93c00f801 GIT binary patch literal 592 zcmV-W0fquab+ZMblY>iIE7D098zV+* zTT~j0NhE`L6$giw77J!k=u*Lgf+*_fAWpW$p^H!#Q{>fm`kniF<7@EmLUPXe&i9>r z?>YC8x?oMcaUOeT-Y_ewC&l}UC^ItFzfel0AmBJoxNz*vF{|z%E+VzJn% z$%Tv~ws6evAnXic#+QP~3;&71Y~!Sp(=S1YoA?sj*!JL|`*n4BUGn< z4qqZF!bEgxlhrUZ`s|yfE4XgvCPLu~?~J`E@wFJp9SQzlw2Omv;0If>{_*{tt+Fnp z4+4~YbxnE8i}C&?vB2|z+yVJ~|IU(dCY{@bKl~o<8fKaekhPmm<`QsPLy_{QiA3*_ zfP^l82t_Ie4WOC$%e^B`Wty!9Gjx<$?xsV#B7}*q$ZppCi((# zlURvOE<5?Q{>1gRFxE$uO6I5l!5Q$Y!2c0~U;{v{ z0I;6|{TBj|3Bm-`8^v+ZCM{+Tk@C zKMkJdBhuo5SG_;2uzimdZC+JC^1>6o@bs~b01d(1a~(KVmttyW#kU|hQp7vB);u21 eB07$~`s*(X%fPuxYR~Kd0000ZsuJ$dNWwos6^7)q&_TBvO! z^em_c@uVlgSMcH!_yB_R;w9Cr^CxVww$XME*?<1|{@G*+DQkI+{+Uv`EY^Z$8yP4? zooc;UGX@(G?|%l-mVr?}iHwCaPfXx=Kw3Jf{H?0>5*f#9^t93TK7O*@o2rwr@B6u_ zv;a02g*|Vu@;TJcR`|=(kVy>=JWSSF6ODpfrS&!pEK+nGtN2NzZjxF!@KNr(>F*qdi62FxlIlWHdJX^p002ovPDHLkV1hyV B(nYU6vofF3DkxFMRZH0PTam{gsP8|8`g9^`OfNOA9UJ<_T58&R3e`m56PIY6i? zz?hj$=A~rqdz__r6AiR-zQP)GfR%{&d@NORnz9kbz zWwOaS-$MF7*oQb1hDYh@C|8+v!P(@yoADi_ng)74osB<9{|8|$gPiK%S@Zw^002ov JPDHLkV1f!8x3vHO literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-mdpi/pet_status_potion.png b/Habitica/res/drawable-mdpi/pet_status_potion.png new file mode 100644 index 0000000000000000000000000000000000000000..34a1c5c92c78b71d853bfa2274513ea637622ace GIT binary patch literal 299 zcmV+`0o4A9P)#ZIr zMF9eMYjB|R3Lsr(f7alu1Bk44o>?VXD1Z4>gUJjWXtluNDPwNH*qRtd@$~FKt1;AE z8J`(VfXMSaf3^JSJ5VEVYseo-8K1xxDYf%F-#K> z3xjcHDoiss3E3tKqPx1=MHpR3VJ#J<6rr$)AP9mOT^Qn|aA!MT&wI8rzRqbgJ8*da zp6B`g-tQdFsyxwftW9tp5R9E77-wt_aV*rQO;(}-<9`(D94=5*3|83bBZcu030C%&#h%1ZYV}1!A@IPaAXaS z9MpOmhalQ1=Qi+<%uX+OC({!zZCqJ>WGH#8kT(`l_+!>Ku!=Q3s`q&Cmj5kb%H%>J zpOE7!0?v|B;#zr2FgiHafembNBL6uC*U|t%C6W;4!75~vb3RhUi6CrwRWircu!_R# zeSqG2F9XQO2Cs1DxuEw4LiCbPITw!erJ{z#DV7t7M8nS&GbIE&Z;5gCVT;$>(H-)C zmIX$KlLvB!F%I0(67Jd7ZHiCRv{fsX!Rd5bou6Kc2rjnQH>v@@-@hi;Z9kbz)@7IT zal}7PwlsxWTU+yXjYq=qd#r{65q$xnXX`?uETi~ zy*+k979yXPmt8hqV|iC`bl1qIoD+9zw$w@@k3o76Tit^8T2j#l zGf=h#6##lMfIWdq7C50hi(t(toQWsS!vDq?Wt`I|D>@LLhq~)fHYLpYqTZ)9D_FN+ z9`z<{VN(JUn7AIsNkdqhsrPnG<6jYyFq?IIg8kYQk;)&~7wL()wlnSP809STIIE2x zni1X}-1Df7b`eJg6X#4}#&Ft)ZP4E=+Uujjl^el6?YUfc2~shYN_oC~`hL+g&C3Xz vF_FEL$N7DOSx^+^@%}?QpZa`0*S`M-cu zwDcg+ilQJkC1^YpJeq&N)}w_M>7_z1f~B+w=1?kHo1#f}d~eg$x3jUk6gv?1{rG-A zJF}S?1Y^wPUk(B|%NlgA(ekATxC@}}KN)|pCL2m7%{Uy!y50S>h@Xvm z;tvCGZfc>wUWYA1u-esgbu67uSB<)xmP)1gkIL^?lnl$hZ9`Jk8<>_wTIVLgMlXV~ zmV2yWt@JWWq1Ja~(L$UcLrvCN#jHWCCS{LVN(1`7UBiyOm!iML`ilL|*GKHL5kYHl zn6P#-Ka+pa@Ch$UYA2Skx+*@)-{^PC^AP+VUrv#RAtUcs-ZpO{nInj3wd=~VV1=|! z1bvvqVV250d-w?u12=D&JJ2Tvvv|qS-fiay`XL~SS|G2>AiWFBWHLvwc-s)2-HoUW zPsbkiGJ|WBpO136Y<=0@d+cb)(PrvA@3e>z_Z7li-_7f@sZ{E0oB4pAjc<G=}g1jQKz$J_ysy2c!vVFp)q4QRAkG8aK9VEA$?J z-)(Pq+Mc$QN|U?uo$veozTf%topbL{DNWTw#0BsPk;{`#UCeJVWQ)v*++la?w7H*!7BX+D6X7xpW#@;pFV( z$5`HVIzlBr&arrT>LVSeV5y^#c$;n8M|9vSd~JRGzN0EXN0^soadzrwA>}q@$`vR=A<*_7Ab)`%5K&$c5Tkddwf_9CLAO6L~gp z%=PJ7&dnNbEL&Wz!wScGVOu!-xiO;Sbt_kG>FRp@Ul*&kLqnh5vT%9kAU5+k)sF#T zTZCx_y}NS!YR9z)Lc=ei3J-8WFcIzhX0S5|+jcR!7C^%a$HU;h!vp6^2KSZx%Y(VO zvr@7RhKHN4Nb+J|4w?O($COZ6(+b63z-x4KEy-AS(3j8=Xdn{rF-Uylf4B3r4xsb# zvM$a{J4?5G)#~12%dg``cf{A*QaoW`Px_>7f6dFQ1Lpgz@CWxV%uFY+ac}U$Hv95% zx<0=LSc^3=Sy7+a%Ojb>(s3Lgh^NT_ zplvLSm-Jl3fjJ1oX7Dqg!Ap3YvoCm$$Cq5H#RM6Er&3W)0uFNvMKcN~4JcQ1Ml-~! z8rC#=1Ktam`q`>7RYazrSktLMRAi(gZdG6zX1a4_LYS;bJb@y6q^g`{$Phc@4|*TP z3QK3kY}5!(J9x=5+-kx}57oTITAaiYW}_$g_IHAa#c#|HxgCv6c8{uZV*JZ9&$K+d z0z-OS^;c_ScDv1fUsTQG?6K-#+ls{6g%mODea^u0apn40))cD9YX-d8FAtZa73SbT zWaLTQuOP@K7hG9O=Y(Oj_XRpm>Uc$k8O#^_>4_iT#Akr zrT#%LDeNZYS1Y5&`opJPIb3qp&11{*I+@dZ71x{h{42L}hUoXN+Dq}fm*f(Y<_ zY+q;)8Ppr%0u(3O8r^BNM}-VC*z5Fi7g-_04CaDrsO=coxVTI=7oHfGTrEC1<7pZ0 z*d6}|bC0hs8avg~)3XO^MKfiUfp1<<9k+g4tF;1C7G=8gO2CQ9x&C}Ew}kz9zuRb^ zOZkJ8U!rwSrraJ=F$YVTo3o(dA78|_!WG$eD?lJV_q*OP$j&z(1hlhU|Jc4TE zAul{R&PNPlQB7*CWg?b*gK;Ng&I+Z@h9hGOOwB08r)K+vWj%z!&zROj(Li^@ZeQCO zz{eN^){D3pjs_lZwMyDz=F$4;-hmBx&N05$m8GZ43efXR5synQhoa+mx!S*I)Jqwh zmzWCk-pv+;p5b&a8nW38Vk)5}_iV*3f8%p65YB7N08?R3_i|0G?M)v!-HT?-08=I= zlbg8pgJpr(iD=1}=^g|vu{^bIbGP8xzxQdWKVXY22cw}XD$xwrO-v=VeCEEQdY=roD4b$CB%q) + + + + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index b66dd1c0b..54a20772b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -5,6 +5,7 @@ import android.graphics.PorterDuff import android.graphics.drawable.BitmapDrawable import android.view.View import android.view.ViewGroup +import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import com.facebook.drawee.view.SimpleDraweeView @@ -86,6 +87,9 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B private val imageView: SimpleDraweeView by bindView(R.id.imageView) private val trainedProgressbar: ProgressBar by bindView(R.id.trainedProgressBar) + private val availableWrapper: ViewGroup by bindView(R.id.items_available_wrapper) + private val eggAvailableView: ImageView by bindView(R.id.egg_available_view) + private val potionAvailableView: ImageView by bindView(R.id.egg_available_view) private val isOwned: Boolean get() = this.ownedPet?.trained ?: 0 > 0 @@ -100,9 +104,18 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B return false } + private val hasEgg: Boolean + get() { + return ownedItems?.get(animal?.animal + "-eggs") != null + } + private val hasPotion: Boolean + get() { + return ownedItems?.get(animal?.color + "-hatchingPotions") != null + } + private val canHatch: Boolean get() { - return ownedItems?.get(animal?.animal + "-eggs") != null && ownedItems?.get(animal?.color + "-hatchingPotions") != null + return hasEgg && hasPotion } init { @@ -121,10 +134,15 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B } else { this.trainedProgressbar.visibility = View.GONE } + availableWrapper.visibility = View.GONE } else { this.trainedProgressbar.visibility = View.GONE this.imageView.alpha = 0.1f + availableWrapper.visibility = View.VISIBLE + eggAvailableView.alpha = if (hasEgg) 1.0f else 0.2f + potionAvailableView.alpha = if (hasPotion) 1.0f else 0.2f } + if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { trainedProgressbar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER } From 60a1b2f5f6f226c5580322c186dd13fc2113472a Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jul 2020 14:53:17 +0200 Subject: [PATCH 14/32] bump build number --- Habitica/build.gradle | 2 +- fastlane/changelog.txt | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 4a834acf2..34c01837e 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -162,7 +162,7 @@ android { multiDexEnabled true 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 2475 + versionCode 2482 versionName "2.7.1" } diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt index 5a85879e6..25826cb08 100644 --- a/fastlane/changelog.txt +++ b/fastlane/changelog.txt @@ -1,5 +1,3 @@ -This update improves performance in some cases and has various improvements to how markdown is handled (Support for images and opening links from the task list) - -We also made some improvements to how the login screen handles troubles it may encounter. +Thank you for helping us with beta testing! Be sure to download this update now for a better Habitica experience! From 19a2f787ddeef25d75a2ac22abae8c974cbfc2c5 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jul 2020 15:51:24 +0200 Subject: [PATCH 15/32] display if pet can be hatched in pet detail screen. Fixes #1341 --- Habitica/res/layout/pet_detail_item.xml | 26 +++++++++++++++++++ .../inventory/PetDetailRecyclerAdapter.kt | 26 ++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Habitica/res/layout/pet_detail_item.xml b/Habitica/res/layout/pet_detail_item.xml index a407af260..74dacd9a2 100644 --- a/Habitica/res/layout/pet_detail_item.xml +++ b/Habitica/res/layout/pet_detail_item.xml @@ -40,4 +40,30 @@ android:layout_height="wrap_content" android:src="@drawable/pet_status_potion" /> + + + + + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index 54a20772b..39192c6f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -89,7 +89,11 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B private val trainedProgressbar: ProgressBar by bindView(R.id.trainedProgressBar) private val availableWrapper: ViewGroup by bindView(R.id.items_available_wrapper) private val eggAvailableView: ImageView by bindView(R.id.egg_available_view) - private val potionAvailableView: ImageView by bindView(R.id.egg_available_view) + private val potionAvailableView: ImageView by bindView(R.id.potion_available_view) + private val itemWrapper: ViewGroup by bindView(R.id.item_wrapper) + private val eggView: SimpleDraweeView by bindView(R.id.egg_view) + private val hatchingPotionView: SimpleDraweeView by bindView(R.id.hatchingPotion_view) + private val checkMarkView: ImageView by bindView(R.id.checkmark_view) private val isOwned: Boolean get() = this.ownedPet?.trained ?: 0 > 0 @@ -126,7 +130,11 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B this.animal = item this.ownedPet = ownedPet this.imageView.alpha = 1.0f + imageView.visibility = View.VISIBLE + itemWrapper.visibility = View.GONE + checkMarkView.visibility = View.GONE val imageName = "social_Pet-$itemType-${item.color}" + itemView.setBackgroundResource(R.drawable.layout_rounded_bg_gray_700) if (this.ownedPet?.trained ?: 0 > 0) { if (this.canRaiseToMount) { this.trainedProgressbar.visibility = View.VISIBLE @@ -138,9 +146,19 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B } else { this.trainedProgressbar.visibility = View.GONE this.imageView.alpha = 0.1f - availableWrapper.visibility = View.VISIBLE - eggAvailableView.alpha = if (hasEgg) 1.0f else 0.2f - potionAvailableView.alpha = if (hasPotion) 1.0f else 0.2f + if (canHatch) { + imageView.visibility = View.GONE + availableWrapper.visibility = View.GONE + itemWrapper.visibility = View.VISIBLE + checkMarkView.visibility = View.VISIBLE + itemView.setBackgroundResource(R.drawable.layout_rounded_bg_gray_700_brand_border) + DataBindingUtils.loadImage(eggView, "Pet_Egg_${item.animal}") + DataBindingUtils.loadImage(hatchingPotionView, "Pet_HatchingPotion_${item.color}") + } else { + availableWrapper.visibility = View.VISIBLE + eggAvailableView.alpha = if (hasEgg) 1.0f else 0.2f + potionAvailableView.alpha = if (hasPotion) 1.0f else 0.2f + } } if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { From 74bceccaf4b552a6f3f682652e643400134c99cc Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jul 2020 16:24:43 +0200 Subject: [PATCH 16/32] Improve using saddle. Fixes #937 --- Habitica/res/drawable-hdpi/pet_checkmark.png | Bin 0 -> 564 bytes Habitica/res/drawable-mdpi/pet_checkmark.png | Bin 0 -> 379 bytes Habitica/res/drawable-xhdpi/pet_checkmark.png | Bin 0 -> 716 bytes .../res/drawable-xxhdpi/pet_checkmark.png | Bin 0 -> 1125 bytes Habitica/res/layout/pet_detail_item.xml | 8 ++-- Habitica/res/values/strings.xml | 1 + .../inventory/PetDetailRecyclerAdapter.kt | 45 ++++++++++++------ .../inventory/items/ItemRecyclerFragment.kt | 7 ++- .../stable/PetDetailRecyclerFragment.kt | 1 - 9 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 Habitica/res/drawable-hdpi/pet_checkmark.png create mode 100644 Habitica/res/drawable-mdpi/pet_checkmark.png create mode 100644 Habitica/res/drawable-xhdpi/pet_checkmark.png create mode 100644 Habitica/res/drawable-xxhdpi/pet_checkmark.png diff --git a/Habitica/res/drawable-hdpi/pet_checkmark.png b/Habitica/res/drawable-hdpi/pet_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..3ddfe89d13a950ea586738af131982fb83db1057 GIT binary patch literal 564 zcmV-40?Yl0P)3`*oR?;vL5iZj%e?Q*ywASx z>@LCs*XM!LSP5`ZVR?Vw$ydMdzQ8Xd)Odd8{Q#nvW-#a^ z5(&lBeSq0C)iP{dV2rz9;)~(0^?&XRWP6x9@Rk_X{qJT-s9?}`8+Nq5^9-Ag#@`Xp zOL3+ECu}!5FB&rg`8PoDman`#wqi{oB1!Rj{Fpc$<6Oq%QGH6emd=@_G>o6v!d51n zWPV;-GS#Y$lPo+3#1E1}gbll`J|$YBA_cApA{fae3s*O&6d2YS1i>25tvqvv?KL+= z`!S7yoRz5TR%?=Nu1EqXc%4b)=R`ZnVmpz)1weI`-0#}DXit0=&!ne1mhDlRlym60 zY`0&E3h{k73^TO4RAZ>Z)`=jgY{k@Q`UW?tDWg>qZo8bfL&eb0fhdEP)B@00004XF*Lt006O% z3;baP0003pNkl4#6F-rqM5QS&AXoyV%s_~U@bj%5FtCh>AHue_tU*fC??-10?sDIcEpV+IxG#3ai|>JG z!Wokrdsq0C9#SbpJ}Ek6g)R!nmjd~$>p}wru=v|)hnEGKGSG#W8`hGwP#SjI*joj||Rh5P;_R;~Dl* zJE)JBbWb|^+biG5mW|d5BD}KQ1r6}D+w8jZ)6M4IS2B<4b~3BFs>%8-XVl%~#U!Sd Z&i{pIasl$6GM4}V002ovPDHLkV1g(zq^$q| literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-xhdpi/pet_checkmark.png b/Habitica/res/drawable-xhdpi/pet_checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b5d1ec380e708c7d3b0abad9fa9268d52f856d GIT binary patch literal 716 zcmV;-0yF)IP)#zOX3k^Iarx>`{& zRohV);w6y`sRDoj(s#UT6_s7w6bkW7Cy`{x*?G4#IM)@T*(vP(@-?U+!(FNpIRfW- z&v!0L{lAG25f%B@Xpk@yn6s}ntP}K32xXFF z0`Z~TKZVJWZvD1;Sg(@0MaPNcjO*KUhdN8M^i0{g$AOLMWYm^E`XA*-mk-KtKZ$l7 z;VCi})zblI7u=G4OUHhv8&6O!8Jwi#H|bDlIDE4#mJki*5k9OZ0STgrlx zY}`U4F}wDm6w-&bYoQeJ!IG?EY;Cu@sXr+#A|h3!5nAx2&<7QzM4`}!M3h!?Z&q)z z_xMe8*Sq)5Bx$1?2bMeMJ7>=M=FFKhOX4vY!@XSR7M;&PW!rr^x%x))lgM&&;|v?; zuiM9%MK8Em_kZiW*_pa!C)e`yhkIFwWH3oYwAu)QwUh_D?GIS+`?{FRMlRbk6(<&Z zbi{z?XddMwQ)PRKFMD3;j9^}&3_{|!Sj1Xi^UNJc-g%Zwv&VJBh{TnsWpyTVbi1Y( zVz}2?<+`PF$X1&wW4HtpR3Ck%|6tvO)YmL?hu-CwJI$w%v1gRTgs`JT9jQZ&f0gw$ zAt#&c^o;W(Zsv34z|~)x6-4j!<;_3*cumNm`+v>M>-~YN<|N)r7p&7&7=%YoF55Nr zIfx~Kfh#f@AMY$!xr*$Y&}fG1C$BoY@O<>(rpVTkYi&0_jc3U9+5NBSV8YohJnw*R zG2(rdF2v-sr5wgRVmu%Oufh)7@Ee#McYczjl`9qrW)sdP@_3)l95?e+>t?G@rM{phGV1AbdM zN2Xg`Z{}xgcV$o~WyHEkM%{+KLhQOqAHrUH8aFlD6 zK8QRtf~~21(|M&{1I}ebKC-PXW+xn+)7arMb9eUITr-vJrfN)_w1;GkR)Idj5WF)z zVjlNFi<(xBD!!MB&17yuNCcd8K6wiI0~iC2P@ zjrQ$et2AYwMp3_5#)4lg+MgbY^$#WNE)dJ(*h7Bg8kEZ6RNm~uSJ@GQeuJ{o=}4NN z_~&2ejJAg60t*}yZG?@w7ZQ!NwVQ7&<)u-QlRLoeYsT$6i{Q@(ceId<+PzTUWWKch zAl+KXc0PTj=7L7jal|rT$Jtc5Vgd@6v_wZFb zKbNH(9H=oSLnQn2v9X|TDe|Jo$pG>_G$JGkhMyl21L?eVcqv3wYZt7!;G%DmywaI< rzC;afK=ZnRtbLIlvAzx3Jq-CSm3Mfp0Uq2@00000NkvXXu0mjf81*i4 literal 0 HcmV?d00001 diff --git a/Habitica/res/layout/pet_detail_item.xml b/Habitica/res/layout/pet_detail_item.xml index 74dacd9a2..99591a480 100644 --- a/Habitica/res/layout/pet_detail_item.xml +++ b/Habitica/res/layout/pet_detail_item.xml @@ -60,10 +60,8 @@ \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index b0b582486..48dbb2f5c 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -1064,4 +1064,5 @@ Unhatched Pet Magic Potions Magic Potion + Use Saddle diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index 39192c6f9..db4aa7abb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -7,11 +7,9 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.ProgressBar -import android.widget.TextView import com.facebook.drawee.view.SimpleDraweeView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.events.commands.FeedCommand -import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.* @@ -22,7 +20,6 @@ import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.bindView import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem -import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.android.habitica.ui.views.dialogs.PetSuggestHatchDialog import io.reactivex.BackpressureStrategy import io.reactivex.Flowable @@ -44,6 +41,7 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B private var ownedMounts: Map? = null private var ownedItems: Map? = null private val equipEvents = PublishSubject.create() + private var ownsSaddles: Boolean = false fun getEquipFlowable(): Flowable { return equipEvents.toFlowable(BackpressureStrategy.DROP) @@ -78,6 +76,12 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B fun setOwnedItems(ownedItems: Map) { this.ownedItems = ownedItems + ownsSaddles = ownedItems.containsKey("Saddle-food") + notifyDataSetChanged() + } + + fun setOwnsSaddles(ownsSaddles: Boolean) { + this.ownsSaddles = ownsSaddles notifyDataSetChanged() } @@ -133,6 +137,8 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B imageView.visibility = View.VISIBLE itemWrapper.visibility = View.GONE checkMarkView.visibility = View.GONE + availableWrapper.visibility = View.GONE + val imageName = "social_Pet-$itemType-${item.color}" itemView.setBackgroundResource(R.drawable.layout_rounded_bg_gray_700) if (this.ownedPet?.trained ?: 0 > 0) { @@ -142,7 +148,6 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B } else { this.trainedProgressbar.visibility = View.GONE } - availableWrapper.visibility = View.GONE } else { this.trainedProgressbar.visibility = View.GONE this.imageView.alpha = 0.1f @@ -154,10 +159,6 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B itemView.setBackgroundResource(R.drawable.layout_rounded_bg_gray_700_brand_border) DataBindingUtils.loadImage(eggView, "Pet_Egg_${item.animal}") DataBindingUtils.loadImage(hatchingPotionView, "Pet_HatchingPotion_${item.color}") - } else { - availableWrapper.visibility = View.VISIBLE - eggAvailableView.alpha = if (hasEgg) 1.0f else 0.2f - potionAvailableView.alpha = if (hasPotion) 1.0f else 0.2f } } @@ -188,16 +189,30 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.equip))) if (canRaiseToMount) { menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.feed))) + if (ownsSaddles) { + menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.use_saddle))) + } } menu.setSelectionRunnable { index -> - if (index == 0) { - animal?.let { - equipEvents.onNext(it.key) + when (index) { + 0 -> { + animal?.let { + equipEvents.onNext(it.key) + } + } + 1 -> { + val event = FeedCommand() + event.usingPet = animal + EventBus.getDefault().post(event) + } + 2 -> { + val event = FeedCommand() + event.usingPet = animal + val saddle = Food() + saddle.key = "Saddle" + event.usingFood = saddle + EventBus.getDefault().post(event) } - } else if (index == 1) { - val event = FeedCommand() - event.usingPet = animal - EventBus.getDefault().post(event) } } menu.show() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 8e5a66086..fda8a9df1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -220,7 +220,12 @@ class ItemRecyclerFragment : BaseFragment(), androidx.swiperefreshlayout.widget. compositeSubscription.add(inventoryRepository.getOwnedItems(type) .doOnNext { items -> if (items.size > 0) { - adapter?.updateData(items) + val filteredItems = if (isFeeding) { + items.where().notEqualTo("key", "Saddle").findAll() + } else { + items + } + adapter?.updateData(filteredItems) } } .map { items -> items.mapNotNull { it.key } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt index f2d6fc3fd..2633da27c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt @@ -14,7 +14,6 @@ import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.models.inventory.Mount import com.habitrpg.android.habitica.models.inventory.Pet import com.habitrpg.android.habitica.models.user.Items -import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapter From 6bc2365232cf3cbded679b654f65d6d92b94a73c Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 20 Jul 2020 16:59:33 +0200 Subject: [PATCH 17/32] update header design. Fixes #1345 --- Habitica/res/layout/activity_main.xml | 5 +++-- Habitica/res/layout/avatar_with_bars.xml | 5 ++--- Habitica/res/layout/value_bar.xml | 8 +------- Habitica/res/values/dimens.xml | 10 +++++----- Habitica/res/values/styles.xml | 1 + .../android/habitica/ui/views/HabiticaIconsHelper.java | 6 +++--- .../com/habitrpg/android/habitica/ui/views/ValueBar.kt | 3 ++- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/Habitica/res/layout/activity_main.xml b/Habitica/res/layout/activity_main.xml index d8006bbde..5af821060 100644 --- a/Habitica/res/layout/activity_main.xml +++ b/Habitica/res/layout/activity_main.xml @@ -32,7 +32,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:titleEnabled="false" - app:contentScrim="?attr/colorPrimary" + app:contentScrim="?attr/colorPrimaryDark" app:expandedTitleMarginEnd="?attr/actionBarSize" app:expandedTitleMarginStart="0dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> @@ -51,6 +51,7 @@ android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" android:theme="@style/Toolbar" + android:background="?attr/colorPrimaryDark" app:layout_collapseMode="pin" app:popupTheme="@style/Theme.AppCompat.Light"> @@ -24,7 +22,6 @@ android:layout_width="match_parent" android:layout_height="@dimen/bar_size" android:layout_toEndOf="@id/ic_header" - android:layout_toRightOf="@id/ic_header" android:orientation="horizontal"/> + android:paddingTop="2dp"> 4dp 140dp - 15dp + 8dp 5dp 2dp 5dp 140dp 147dp - 108dp - 113dp + 94dp + 98dp 219dp @@ -64,9 +64,9 @@ 81dp 99dp 124dp - 10dp + 6dp 16dp - 7dp + 3dp 13dp 4dp diff --git a/Habitica/res/values/styles.xml b/Habitica/res/values/styles.xml index 44fe19c92..55e27fe34 100644 --- a/Habitica/res/values/styles.xml +++ b/Habitica/res/values/styles.xml @@ -257,6 +257,7 @@ @@ -65,7 +66,8 @@ @color/red_100 @color/red_500 @color/red_5 - @color/red_100 + @color/red_50 + @color/red_1 + + @@ -387,6 +387,7 @@ @dimen/pill_horizontal_padding @dimen/pill_vertical_padding @dimen/pill_vertical_padding + @color/gray_200 @@ -649,9 +653,9 @@ @color/taskform_gray ?attr/colorPrimaryText @color/gray_300 - @color/gray_400 - @color/brand_400 - @color/brand_400 + ?attr/colorPrimary + ?attr/colorPrimary + ?attr/colorPrimary @color/brand_400 diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt index 102b47cc1..1f3b97fe7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Animal-Extensions.kt @@ -9,16 +9,14 @@ fun Animal.getTranslatedType(c: Context?): String { return type } - var currType: String = when (type) { - "drop" -> c?.getString(R.string.standard).toString() - "quest" -> c?.getString(R.string.quest).toString() - "wacky" -> c?.getString(R.string.wacky).toString() - "special" -> c?.getString(R.string.special).toString() - "premium" -> c?.getString(R.string.magic_potion).toString() + return when (type) { + "drop" -> c.getString(R.string.standard) + "quest" -> c.getString(R.string.quest) + "wacky" -> c.getString(R.string.wacky) + "special" -> c.getString(R.string.special) + "premium" -> c.getString(R.string.magic_potion) else -> { type } } - - return currType } \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt index 2f38a4f59..f2fe79897 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt @@ -118,12 +118,10 @@ class TaskFormActivity : BaseActivity() { private var tintColor: Int = 0 set(value) { field = value - upperTextWrapper.setBackgroundColor(value) taskDifficultyButtons.tintColor = value habitScoringButtons.tintColor = value habitResetStreakButtons.tintColor = value taskSchedulingControls.tintColor = value - supportActionBar?.setBackgroundDrawable(ColorDrawable(value)) updateTagViewsColors() } @@ -153,12 +151,22 @@ class TaskFormActivity : BaseActivity() { } else { "purple" } - super.onCreate(savedInstanceState) + + if (forcedTheme == "yellow") { + taskDifficultyButtons.textTintColor = ContextCompat.getColor(this, R.color.yellow_5) + habitScoringButtons.textTintColor = ContextCompat.getColor(this, R.color.yellow_5) + } + + setSupportActionBar(toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true) tintColor = getThemeColor(R.attr.taskFormTint) + val upperTintColor = getThemeColor(R.attr.colorAccent) + supportActionBar?.setBackgroundDrawable(ColorDrawable(upperTintColor)) + upperTextWrapper.setBackgroundColor(upperTintColor) + isChallengeTask = bundle.getBoolean(IS_CHALLENGE_TASK, false) @@ -172,7 +180,7 @@ class TaskFormActivity : BaseActivity() { setTagViews() }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(userRepository.getUser().subscribe(Consumer { - usesTaskAttributeStats = it.preferences?.allocationMode == "taskbased" + usesTaskAttributeStats = it.preferences?.allocationMode == "taskbased" && it.preferences?.automaticAllocation == true configureForm() }, RxErrorHandler.handleEmptyError())) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt index f99e55976..259eec1a0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt @@ -36,7 +36,7 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) { when (val obj = this.itemList[position]) { - is String -> (holder as? SectionViewHolder)?.bind(obj) + is StableSection -> (holder as? SectionViewHolder)?.bind(obj) is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index 1ceeb000f..e0b46ec18 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -4,6 +4,7 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.facebook.drawee.view.SimpleDraweeView import com.habitrpg.android.habitica.R @@ -24,6 +25,7 @@ import io.reactivex.subjects.PublishSubject class StableRecyclerAdapter : RecyclerView.Adapter() { + var shopSpriteSuffix: String? = null private var eggs: Map = mapOf() var animalIngredientsRetriever: ((Animal) -> Pair)? = null var itemType: String? = null @@ -53,7 +55,14 @@ class StableRecyclerAdapter : RecyclerView.Adapter() { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (val item = this.itemList[position]) { "header" -> (holder as? StableHeaderViewHolder)?.bind() - is StableSection -> (holder as? SectionViewHolder)?.bind(item) + is StableSection -> { + if (item.key == "drop") { + val params = holder.itemView.layoutParams as GridLayoutManager.LayoutParams + params.topMargin = -30 + holder.itemView.layoutParams = params + } + (holder as? SectionViewHolder)?.bind(item) + } is Animal -> { val isIndividualAnimal = item.type == "special" || item.type == "wacky" if (isIndividualAnimal) { @@ -109,11 +118,12 @@ class StableRecyclerAdapter : RecyclerView.Adapter() { notifyDataSetChanged() } - internal class StableHeaderViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(parent.inflate(R.layout.shop_header)) { + internal inner class StableHeaderViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(parent.inflate(R.layout.shop_header)) { private var binding: ShopHeaderBinding = ShopHeaderBinding.bind(itemView) fun bind() { + binding.npcBannerView.shopSpriteSuffix = shopSpriteSuffix ?: "" binding.npcBannerView.identifier = "stable" binding.namePlate.setText(R.string.stable_owner) binding.descriptionView.visibility = View.GONE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt index 2551b98b1..988b5337f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt @@ -135,7 +135,8 @@ class MountDetailRecyclerFragment : BaseMainFragment() { for (mount in unsortedAnimals) { if (mount.type == "wacky" || mount.type == "special") continue if (mount.type != lastMount?.type) { - currentSection = StableSection(mount.type, mount.getTranslatedType(context)) + val title = context?.getString(R.string.pet_category, mount.getTranslatedType(context)) + currentSection = StableSection(mount.type, title ?: "") items.add(currentSection) } currentSection?.let { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt index 37b6b6c9f..a9e9c4f2a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt @@ -24,6 +24,7 @@ import com.habitrpg.android.habitica.ui.helpers.bindView import com.habitrpg.android.habitica.ui.helpers.resetViews import io.reactivex.functions.BiFunction import io.reactivex.functions.Consumer +import io.reactivex.rxkotlin.combineLatest import io.realm.RealmResults import org.greenrobot.eventbus.Subscribe import java.util.ArrayList @@ -140,35 +141,35 @@ class PetDetailRecyclerFragment : BaseMainFragment() { } .subscribe(Consumer { adapter.setOwnedMounts(it) }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(inventoryRepository.getOwnedItems(true).subscribe(Consumer { adapter.setOwnedItems(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(inventoryRepository.getPets(animalType, animalGroup, animalColor).zipWith(inventoryRepository.getOwnedPets() + compositeSubscription.add(inventoryRepository.getPets(animalType, animalGroup, animalColor).combineLatest(inventoryRepository.getOwnedPets() .map { ownedPets -> val petMap = mutableMapOf() ownedPets.forEach { petMap[it.key ?: ""] = it } return@map petMap }.doOnNext { adapter.setOwnedPets(it) - }, BiFunction, Map, List> { unsortedAnimals, ownedAnimals -> + }).map { val items = mutableListOf() var lastPet: Pet? = null var currentSection: StableSection? = null - for (pet in unsortedAnimals) { + for (pet in it.first) { if (pet.type == "wacky" || pet.type == "special") continue if (pet.type != lastPet?.type) { - currentSection = StableSection(pet.type, pet.getTranslatedType(context)) + val title = context?.getString(R.string.pet_category, pet.getTranslatedType(context)) + currentSection = StableSection(pet.type, title ?: "") items.add(currentSection) } - currentSection?.let { - it.totalCount += 1 - if (ownedAnimals.containsKey(pet.key)) { - it.ownedCount += 1 + currentSection?.let {section -> + section.totalCount += 1 + if (it.second.containsKey(pet.key)) { + section.ownedCount += 1 } } items.add(pet) lastPet = pet } items - }) - .subscribe(Consumer { adapter.setItemList(it) }, RxErrorHandler.handleEmptyError())) + }.subscribe(Consumer { adapter.setItemList(it) }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(inventoryRepository.getMounts(animalType, animalGroup, animalColor).subscribe(Consumer> { adapter.setExistingMounts(it) }, RxErrorHandler.handleEmptyError())) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt index 9e8788e91..0fd1eb5c7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt @@ -10,6 +10,7 @@ import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.extensions.getTranslatedType import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.Animal import com.habitrpg.android.habitica.models.inventory.Egg @@ -31,6 +32,8 @@ class StableRecyclerFragment : BaseFragment() { @Inject lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var configManager: AppConfigManager private val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView) private val emptyView: TextView? by bindView(R.id.emptyView) @@ -92,6 +95,7 @@ class StableRecyclerFragment : BaseFragment() { Pair(egg as? Egg, potion as? HatchingPotion) } adapter?.itemType = this.itemType + adapter?.shopSpriteSuffix = configManager.shopSpriteSuffix() recyclerView?.adapter = adapter recyclerView?.itemAnimator = SafeDefaultItemAnimator() @@ -185,7 +189,12 @@ class StableRecyclerFragment : BaseFragment() { if (items.size > 0 && items[items.size - 1].javaClass == StableSection::class.java) { items.removeAt(items.size - 1) } - val section = StableSection(animal.type, animal.getTranslatedType(context)) + val title = if (itemType == "pets") { + context?.getString(R.string.pet_category, animal.getTranslatedType(context)) + } else { + context?.getString(R.string.mount_category, animal.getTranslatedType(context)) + } + val section = StableSection(animal.type, title ?: "") items.add(section) lastSection = section } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt index 053bda468..ebe9baf97 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt @@ -61,7 +61,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject { - val itemContent = PurchaseDialogItemContent(context) - if (shopItem.canPurchaseBulk) { - itemContent.stepperView.visibility = View.VISIBLE - itemContent.stepperView.onValueChanged = { - purchaseQuantity = it.toInt() - updatePurchaseTotal() - } - } else { - itemContent.stepperView.visibility = View.GONE - } - contentView = itemContent - } - shopItem.isTypeQuest -> { + shopItem.isTypeItem -> contentView = PurchaseDialogItemContent(context) + shopItem.isTypeQuest -> { contentView = PurchaseDialogQuestContent(context) inventoryRepository.getQuestContent(shopItem.key).firstElement().subscribe(Consumer { contentView.setQuestContent(it) }, RxErrorHandler.handleEmptyError()) } - shopItem.isTypeGear -> { + shopItem.isTypeGear -> { contentView = PurchaseDialogGearContent(context) inventoryRepository.getEquipment(shopItem.key).firstElement().subscribe(Consumer { contentView.setEquipment(it) }, RxErrorHandler.handleEmptyError()) checkGearClass() } - "gems" == shopItem.purchaseType -> { - val gemContent = PurchaseDialogGemsContent(context) - gemContent.stepperView.onValueChanged = { + "gems" == shopItem.purchaseType -> contentView = PurchaseDialogGemsContent(context) + else -> contentView = PurchaseDialogBaseContent(context) + } + + val stepperView = contentView.findViewById(R.id.stepper_view) + if (stepperView != null) { + if (shopItem.canPurchaseBulk) { + stepperView.visibility = View.VISIBLE + stepperView.onValueChanged = { purchaseQuantity = it.toInt() updatePurchaseTotal() } - contentView = gemContent + } else { + stepperView.visibility = View.GONE } - else -> contentView = PurchaseDialogBaseContent(context) } amountErrorLabel = contentView.findViewById(R.id.amount_error_label) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/HabitScoringButtonsView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/HabitScoringButtonsView.kt index 1ab328c21..65d9b3e95 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/HabitScoringButtonsView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/HabitScoringButtonsView.kt @@ -29,13 +29,14 @@ class HabitScoringButtonsView @JvmOverloads constructor( var tintColor: Int = ContextCompat.getColor(context, R.color.brand_300) + var textTintColor: Int? = null var isPositive = true set(value) { field = value positiveImageView.setImageDrawable(HabiticaIconsHelper.imageOfHabitControlPlus(tintColor, value).asDrawable(resources)) if (value) { - positiveTextView.setTextColor(tintColor) + positiveTextView.setTextColor(textTintColor ?: tintColor) positiveView.contentDescription = toContentDescription(R.string.positive_habit_form, R.string.on) positiveTextView.typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) } else { @@ -50,7 +51,7 @@ class HabitScoringButtonsView @JvmOverloads constructor( field = value negativeImageView.setImageDrawable(HabiticaIconsHelper.imageOfHabitControlMinus(tintColor, value).asDrawable(resources)) if (value) { - negativeTextView.setTextColor(tintColor) + negativeTextView.setTextColor(textTintColor ?: tintColor) negativeView.contentDescription = toContentDescription(R.string.negative_habit_form, R.string.on) negativeTextView.typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) } else { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskDifficultyButtons.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskDifficultyButtons.kt index 858dc4be9..50bebcf13 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskDifficultyButtons.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskDifficultyButtons.kt @@ -21,6 +21,7 @@ class TaskDifficultyButtons @JvmOverloads constructor( ) : LinearLayout(context, attrs, defStyleAttr) { var tintColor: Int = ContextCompat.getColor(context, R.color.brand_300) + var textTintColor: Int? = null var selectedDifficulty: Float = 1f set(value) { field = value @@ -58,7 +59,7 @@ class TaskDifficultyButtons @JvmOverloads constructor( var difficultyColor = ContextCompat.getColor(context, R.color.white) if (isActive) { view.findViewById(R.id.image_view).background.mutate().setTint(tintColor) - view.findViewById(R.id.text_view).setTextColor(tintColor) + view.findViewById(R.id.text_view).setTextColor(textTintColor ?: tintColor) view.findViewById(R.id.text_view).typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL) } else { view.findViewById(R.id.image_view).background.mutate().setTint(ContextCompat.getColor(context, R.color.taskform_gray)) diff --git a/Habitica/staff/release/output.json b/Habitica/staff/release/output.json index de4c44ce8..dd6cdca9a 100644 --- a/Habitica/staff/release/output.json +++ b/Habitica/staff/release/output.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 2459, - "versionName": "2459", + "versionCode": 2500, + "versionName": "2500", "enabled": true, "outputFile": "Habitica-staff-release.apk" } From 205a23bb2da32eb72ceb497140c27d7726138b35 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 30 Jul 2020 13:06:35 +0200 Subject: [PATCH 32/32] fix some minor crashes --- Habitica/res/layout/pet_detail_item.xml | 6 +++--- .../com/habitrpg/android/habitica/helpers/Keyhelper.kt | 3 +++ .../habitrpg/android/habitica/helpers/PurchaseHandler.kt | 7 ++++++- .../notifications/HabiticaFirebaseMessagingService.kt | 6 ++++-- .../ui/fragments/tasks/TaskRecyclerViewFragment.kt | 3 +++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Habitica/res/layout/pet_detail_item.xml b/Habitica/res/layout/pet_detail_item.xml index 82285c2cc..67776ae04 100644 --- a/Habitica/res/layout/pet_detail_item.xml +++ b/Habitica/res/layout/pet_detail_item.xml @@ -10,12 +10,12 @@ diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Keyhelper.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Keyhelper.kt index 52fec9c52..3de8006b0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Keyhelper.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/Keyhelper.kt @@ -12,6 +12,7 @@ import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.IOException import java.io.UnsupportedEncodingException +import java.lang.IllegalStateException import java.math.BigInteger import java.security.* import java.util.* @@ -188,6 +189,8 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore null } catch (e: GeneralSecurityException) { null + } catch (e: IllegalStateException) { + null } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt index 296dc705e..35713840b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt @@ -5,6 +5,7 @@ import android.content.Intent import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.proxy.CrashlyticsProxy import org.solovyev.android.checkout.* +import java.lang.NullPointerException import java.util.* import javax.annotation.Nonnull @@ -92,7 +93,11 @@ class PurchaseHandler(activity: Activity, val crashlyticsProxy: CrashlyticsProxy private fun loadInventory(type: String, skus: List, callback: Inventory.Callback) { val request = Inventory.Request.create().loadAllPurchases().loadSkus(type, skus) if (request != null) { - inventory?.load(request, callback) + try { + inventory?.load(request, callback) + } catch (e: NullPointerException) { + return + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt index c8cc4127e..a895ba525 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt @@ -19,14 +19,16 @@ class HabiticaFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { userComponent?.inject(this) - pushNotificationManager.displayNotification(remoteMessage) + if (this::pushNotificationManager.isInitialized) { + pushNotificationManager.displayNotification(remoteMessage) + } } override fun onNewToken(s: String) { super.onNewToken(s) userComponent?.inject(this) val refreshedToken = FirebaseInstanceId.getInstance().token - if (refreshedToken != null) { + if (refreshedToken != null && this::pushNotificationManager.isInitialized) { pushNotificationManager.refreshedToken = refreshedToken } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt index f513ef811..5e9e0c175 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt @@ -291,6 +291,9 @@ open class TaskRecyclerViewFragment : BaseFragment(), androidx.swiperefreshlayou protected fun showBrokenChallengeDialog(task: Task) { context?.let { + if (!task.isValid) { + return + } taskRepository.getTasksForChallenge(task.challengeID).subscribe(Consumer { tasks -> val taskCount = tasks.size val dialog = HabiticaAlertDialog(it)