From 2fb6f8576739d68581e1408721871a434786e856 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Wed, 31 Jul 2019 11:02:46 +0200 Subject: [PATCH 01/96] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 30 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..781ca3b7b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,30 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'Type: Bug' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Smartphone (please complete the following information):** + - Device: [e.g. Moto G5] + - OS: [e.g. Android 9] + - App Version: [e.g. 2.2] + - Habitica Username: + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..63b82974a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'Type: Feature' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 8236aa3feece28865017d90277d45866f8702a87 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Wed, 31 Jul 2019 11:21:36 +0200 Subject: [PATCH 02/96] Fix typo --- Habitica/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 79f990a3d..4fa427370 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -763,7 +763,7 @@ Take on quests with friends or on your own. Battle monsters, create Challenges, and help yourself stay accountable through Parties. Play Habitica in a Party Give a Party member the username found below and they can send you an invite - Give the username below to a friend or head to the %s to meet potential comrades!e + Give the username below to a friend or head to the %s to meet potential comrades! Give them your User ID or have them scan your QR code while inviting Want to join a party? Open website to create party From e40e768888584370970fc175869084fe2c64d2ef Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 1 Jul 2019 16:07:16 +0200 Subject: [PATCH 03/96] Fix hatching pet dialog --- .../habitica/ui/activities/MainActivity.kt | 33 +++++++++++++- .../inventory/items/ItemRecyclerFragment.kt | 43 +++---------------- 2 files changed, 38 insertions(+), 38 deletions(-) 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 033adce5f..43bb84890 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 @@ -41,7 +41,6 @@ import com.habitrpg.android.habitica.events.ShowConnectionProblemEvent import com.habitrpg.android.habitica.events.ShowSnackbarEvent import com.habitrpg.android.habitica.events.commands.FeedCommand import com.habitrpg.android.habitica.extensions.DateUtils -import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler import com.habitrpg.android.habitica.helpers.* import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager @@ -49,6 +48,8 @@ import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase import com.habitrpg.android.habitica.interactors.NotifyUserUseCase import com.habitrpg.android.habitica.models.TutorialStep +import com.habitrpg.android.habitica.models.inventory.Egg +import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.models.notifications.LoginIncentiveData import com.habitrpg.android.habitica.models.responses.MaintenanceResponse import com.habitrpg.android.habitica.models.responses.TaskScoringResult @@ -59,7 +60,6 @@ import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel import com.habitrpg.android.habitica.ui.TutorialView import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils -import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil import com.habitrpg.android.habitica.ui.helpers.bindOptionalView import com.habitrpg.android.habitica.ui.helpers.bindView import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel @@ -674,6 +674,35 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { } } + fun hatchPet(potion: HatchingPotion, egg: Egg) { + compositeSubscription.add(this.inventoryRepository.hatchPet(egg, potion) { + val petWrapper = View.inflate(this, R.layout.pet_imageview, null) as? FrameLayout + val petImageView = petWrapper?.findViewById(R.id.pet_imageview) as? SimpleDraweeView + + DataBindingUtils.loadImage(petImageView, "Pet-" + egg.key + "-" + potion.key) + val potionName = potion.text + val eggName = egg.text + val dialog = HabiticaAlertDialog(this) + dialog.setTitle(getString(R.string.hatched_pet_title, potionName, eggName)) + dialog.setAdditionalContentView(petWrapper) + dialog.addButton(R.string.onwards, true) { hatchingDialog, _ -> hatchingDialog.dismiss() } + dialog.addButton(R.string.share, false) { hatchingDialog, _ -> + val event1 = ShareEvent() + event1.sharedMessage = getString(R.string.share_hatched, potionName, eggName) + " https://habitica.com/social/hatch-pet" + val petImageSideLength = 140 + val sharedImage = Bitmap.createBitmap(petImageSideLength, petImageSideLength, Bitmap.Config.ARGB_8888) + val canvas = Canvas(sharedImage) + canvas.drawColor(ContextCompat.getColor(this, R.color.brand_300)) + petImageView?.drawable?.setBounds(0, 0, petImageSideLength, petImageSideLength) + petImageView?.drawable?.draw(canvas) + event1.shareImage = sharedImage + EventBus.getDefault().post(event1) + hatchingDialog.dismiss() + } + dialog?.show() + }.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) + } + companion object { const val SELECT_CLASS_RESULT = 11 const val GEM_PURCHASE_REQUEST = 111 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 55517d23d..d7d6b34e9 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 @@ -1,34 +1,30 @@ package com.habitrpg.android.habitica.ui.fragments.inventory.items -import android.graphics.Bitmap -import android.graphics.Canvas import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.Window import android.widget.Button -import android.widget.FrameLayout import android.widget.TextView -import androidx.core.content.ContextCompat -import com.facebook.drawee.view.SimpleDraweeView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.UserRepository -import com.habitrpg.android.habitica.events.ShareEvent import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment -import com.habitrpg.android.habitica.ui.helpers.* -import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog +import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport +import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.helpers.resetViews import io.reactivex.functions.Consumer -import org.greenrobot.eventbus.EventBus import javax.inject.Inject class ItemRecyclerFragment : BaseFragment() { @@ -191,33 +187,8 @@ class ItemRecyclerFragment : BaseFragment() { } private fun hatchPet(potion: HatchingPotion, egg: Egg) { - compositeSubscription.add(this.inventoryRepository.hatchPet(egg, potion) { - dismiss() - val petWrapper = View.inflate(context, R.layout.pet_imageview, null) as? FrameLayout - val petImageView = petWrapper?.findViewById(R.id.pet_imageview) as? SimpleDraweeView - - DataBindingUtils.loadImage(petImageView, "Pet-" + egg.key + "-" + potion.key) - val potionName = potion.text - val eggName = egg.text - val dialog = context?.let { HabiticaAlertDialog(it) } - dialog?.setTitle(getString(R.string.hatched_pet_title, potionName, eggName)) - dialog?.setAdditionalContentView(petWrapper) - dialog?.addButton(R.string.onwards, true) { hatchingDialog, _ -> hatchingDialog.dismiss() } - dialog?.addButton(R.string.share, false) { hatchingDialog, _ -> - val event1 = ShareEvent() - event1.sharedMessage = getString(R.string.share_hatched, potionName, eggName) + " https://habitica.com/social/hatch-pet" - val petImageSideLength = 140 - val sharedImage = Bitmap.createBitmap(petImageSideLength, petImageSideLength, Bitmap.Config.ARGB_8888) - val canvas = Canvas(sharedImage) - context?.let { canvas.drawColor(ContextCompat.getColor(it, R.color.brand_300)) } - petImageView?.drawable?.setBounds(0, 0, petImageSideLength, petImageSideLength) - petImageView?.drawable?.draw(canvas) - event1.shareImage = sharedImage - EventBus.getDefault().post(event1) - hatchingDialog.dismiss() - } - dialog?.show() - }.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) + dismiss() + (activity as? MainActivity)?.hatchPet(potion, egg) } private fun loadItems() { From fa02797e64eff21741df52f536dd931d6e3672d1 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 14:39:24 +0200 Subject: [PATCH 04/96] Fix content mapping --- Habitica/build.gradle | 4 +- .../RealmContentLocalRepository.kt | 6 +-- .../habitica/models/ContentResult.java | 45 ------------------- .../android/habitica/models/ContentResult.kt | 34 ++++++++++++++ .../habitica/utils/ContentDeserializer.kt | 8 ---- 5 files changed, 39 insertions(+), 58 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.kt diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 1926512e8..2364cc749 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -149,8 +149,8 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" multiDexEnabled true - versionCode 2169 - versionName "2.0" + versionCode 2174 + versionName "2.0.1" } lintOptions { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt index 39cbdf721..53b1065b6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt @@ -13,9 +13,9 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository( override fun saveContent(contentResult: ContentResult) { realm.executeTransactionAsync { realm1 -> - realm1.insertOrUpdate(contentResult.potion) - realm1.insertOrUpdate(contentResult.armoire) - realm1.insertOrUpdate(contentResult.gear.flat) + contentResult.potion?.let { realm1.insertOrUpdate(it) } + contentResult.armoire?.let { realm1.insertOrUpdate(it) } + contentResult.gear?.flat?.let { realm1.insertOrUpdate(it) } realm1.insertOrUpdate(contentResult.quests) realm1.insertOrUpdate(contentResult.eggs) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.java deleted file mode 100644 index 50ee283ac..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.habitrpg.android.habitica.models; - -import com.habitrpg.android.habitica.models.inventory.Customization; -import com.habitrpg.android.habitica.models.inventory.Egg; -import com.habitrpg.android.habitica.models.inventory.Equipment; -import com.habitrpg.android.habitica.models.inventory.Food; -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.inventory.QuestContent; -import com.habitrpg.android.habitica.models.inventory.SpecialItem; - -import java.util.List; - -import io.realm.RealmList; - -/** - * Created by Negue on 15.07.2015. - */ -public class ContentResult { - - public Equipment potion; - - public Equipment armoire; - - public ContentGear gear; - - public RealmList quests; - public RealmList eggs; - public RealmList food; - public RealmList hatchingPotions; - - public RealmList pets; - - public RealmList mounts; - - public List spells; - - public RealmList appearances; - public RealmList backgrounds; - - public RealmList faq; - public RealmList special; -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.kt new file mode 100644 index 000000000..3c890d842 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/ContentResult.kt @@ -0,0 +1,34 @@ +package com.habitrpg.android.habitica.models + +import com.habitrpg.android.habitica.models.inventory.* +import io.realm.RealmList + +/** + * Created by Negue on 15.07.2015. + */ +class ContentResult { + + var potion: Equipment? = null + + var armoire: Equipment? = null + + var gear: ContentGear? = null + + var quests = RealmList() + var eggs = RealmList() + var food = RealmList() + var hatchingPotions = RealmList() + + var pets = RealmList() + + var mounts = RealmList() + + var spells = RealmList() + + var appearances = RealmList() + var backgrounds = RealmList() + + var faq = RealmList() + var special = RealmList() +} + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt index 84e816f0b..eb002c423 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt @@ -14,7 +14,6 @@ import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.* import io.realm.RealmList import java.lang.reflect.Type -import java.util.* class ContentDeserializer : JsonDeserializer { @@ -29,25 +28,20 @@ class ContentDeserializer : JsonDeserializer { result.armoire = context.deserialize(obj.get("armoire"), Equipment::class.java) result.gear = context.deserialize(obj.get("gear"), ContentGear::class.java) - result.quests = RealmList() for (entry in obj.get("quests").asJsonObject.entrySet()) { result.quests.add(context.deserialize(entry.value, QuestContent::class.java)) result.quests.forEach { it.key = it.key } } - result.eggs = RealmList() for (entry in obj.get("eggs").asJsonObject.entrySet()) { result.eggs.add(context.deserialize(entry.value, Egg::class.java)) } - result.food = RealmList() for (entry in obj.get("food").asJsonObject.entrySet()) { result.food.add(context.deserialize(entry.value, Food::class.java)) } - result.hatchingPotions = RealmList() for (entry in obj.get("hatchingPotions").asJsonObject.entrySet()) { result.hatchingPotions.add(context.deserialize(entry.value, HatchingPotion::class.java)) } - result.pets = RealmList() val pets = obj.getAsJsonObject("petInfo") for (key in pets.keySet()) { val pet = Pet() @@ -67,7 +61,6 @@ class ContentDeserializer : JsonDeserializer { result.pets.add(pet) } - result.mounts = RealmList() val mounts = obj.getAsJsonObject("mountInfo") for (key in mounts.keySet()) { val mount = Mount() @@ -85,7 +78,6 @@ class ContentDeserializer : JsonDeserializer { } result.mounts.add(mount) } - result.spells = ArrayList() for ((classname, value) in obj.getAsJsonObject("spells").entrySet()) { val classObject = value.asJsonObject From 707fffd7d5f5d06d188e280eaf8c1e0184dc0b0e Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 14:39:31 +0200 Subject: [PATCH 05/96] update changelog --- fastlane/changelog.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt index ac4be0893..25bf9d3ed 100644 --- a/fastlane/changelog.txt +++ b/fastlane/changelog.txt @@ -1,4 +1,3 @@ -This beta update stores the apps authentication credentials more securely. The app should automatically update to the new storage method without you having to log in again. If you experience any issues with this, please report them through the in-app-reporting option or to admin@habitica.com -We updated the app with a new modal design +We fixed a minor crash in version 2.0.1. -Be sure to download this update now for a better Habitica experience! +In the latest update, version 2.0 brings you a redesigned way to add new tasks as well as a new Notifications section in the Menu so that you can stay up to date with your Party and Guilds! We also fixed bugs related to task editing, Shops, and Rewards. Be sure to download this update now for a better Habitica experience! From b1abca8e1123aad49056a8f223c8d6f4c2493688 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 14:39:57 +0200 Subject: [PATCH 06/96] fix loading user object --- .../habitica/ui/fragments/BaseMainFragment.kt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt index 01c19915c..897ef5822 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt @@ -45,16 +45,10 @@ abstract class BaseMainFragment : BaseFragment() { } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { super.onCreateView(inflater, container, savedInstanceState) - if (savedInstanceState != null && savedInstanceState.containsKey("userId")) { - val userId = savedInstanceState.getString("userId") - if (userId != null) { - compositeSubscription.add(userRepository.getUser(userId).subscribe(Consumer { habitRPGUser -> user = habitRPGUser }, RxErrorHandler.handleEmptyError())) - } - } + compositeSubscription.add(userRepository.getUser().subscribe(Consumer { user = it }, RxErrorHandler.handleEmptyError())) if (this.usesBottomNavigation) { bottomNavigation?.visibility = View.VISIBLE @@ -96,14 +90,6 @@ abstract class BaseMainFragment : BaseFragment() { super.onDestroy() } - override fun onSaveInstanceState(outState: Bundle) { - if (user?.isValid == true) { - outState.putString("userId", user?.id) - } - - super.onSaveInstanceState(outState) - } - private fun hideToolbar() { activity?.avatarWithBars?.visibility = View.GONE } From 8caca96e41f382a5520ea7ffcb12dbe65503013b Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 14:40:14 +0200 Subject: [PATCH 07/96] Fix task response sometimes not showing --- .../data/implementation/TaskRepositoryImpl.kt | 87 ++++++++++--------- .../data/local/TaskLocalRepository.kt | 2 + .../RealmTaskLocalRepository.kt | 16 ++++ .../tasks/TaskRecyclerViewFragment.kt | 12 +-- 4 files changed, 67 insertions(+), 50 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt index 524bcae90..ff2d006a9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt @@ -82,61 +82,66 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli if (lastTaskAction > now - 500 && !force || id == null) { return Flowable.empty() } + lastTaskAction = now return this.apiClient.postTaskDirection(id, (if (up) TaskDirection.UP else TaskDirection.DOWN).text) - .map { res -> + .flatMapMaybe { + // There are cases where the user object is not set correctly. So the app refetches it as a fallback + if (user == null) { + localRepository.getUser(userID).firstElement() + } else { + Maybe.just(user) + }.map { user -> Pair(it, user) } + } + .map { (res, user): Pair -> // save local task changes val result = TaskScoringResult() - if (user != null) { - val stats = user.stats + val stats = user.stats - result.healthDelta = res.hp - (stats?.hp ?: 0.0) - result.experienceDelta = res.exp - (stats?.exp ?: 0.0) - result.manaDelta = res.mp - (stats?.mp ?: 0.0) - result.goldDelta = res.gp - (stats?.gp ?: 0.0) - result.hasLeveledUp = res.lvl > stats?.lvl ?: 0 - result.questDamage = res._tmp?.quest?.progressDelta - result.drop = res._tmp?.drop - if (localData == null) { - notifyFunc?.invoke(result) - } + result.healthDelta = res.hp - (stats?.hp ?: 0.0) + result.experienceDelta = res.exp - (stats?.exp ?: 0.0) + result.manaDelta = res.mp - (stats?.mp ?: 0.0) + result.goldDelta = res.gp - (stats?.gp ?: 0.0) + result.hasLeveledUp = res.lvl > stats?.lvl ?: 0 + result.questDamage = res._tmp?.quest?.progressDelta + result.drop = res._tmp?.drop + if (localData == null) { + notifyFunc?.invoke(result) } handleTaskResponse(user, res, task, up, localData?.delta ?: 0f) result } } - private fun handleTaskResponse(user: User?, res: TaskDirectionData, task: Task, up: Boolean, localDelta: Float) { - if (user != null) { - val stats = user.stats - this.localRepository.executeTransaction { - if (!task.isValid) { - return@executeTransaction - } - if (task.type != "reward" && (task.value - localDelta) + res.delta != task.value) { - task.value = (task.value - localDelta) + res.delta - if (Task.TYPE_DAILY == task.type || Task.TYPE_TODO == task.type) { - task.completed = up - if (Task.TYPE_DAILY == task.type && up) { - task.streak = (task.streak ?: 0) + 1 - } - } else if (Task.TYPE_HABIT == task.type) { - if (up) { - task.counterUp = (task.counterUp ?: 0) + 1 - } else { - task.counterDown = (task.counterDown ?: 0) + 1 - } + private fun handleTaskResponse(user: User, res: TaskDirectionData, task: Task, up: Boolean, localDelta: Float) { + val stats = user.stats + this.localRepository.executeTransaction { + if (!task.isValid) { + return@executeTransaction + } + if (task.type != "reward" && (task.value - localDelta) + res.delta != task.value) { + task.value = (task.value - localDelta) + res.delta + if (Task.TYPE_DAILY == task.type || Task.TYPE_TODO == task.type) { + task.completed = up + if (Task.TYPE_DAILY == task.type && up) { + task.streak = (task.streak ?: 0) + 1 + } + } else if (Task.TYPE_HABIT == task.type) { + if (up) { + task.counterUp = (task.counterUp ?: 0) + 1 + } else { + task.counterDown = (task.counterDown ?: 0) + 1 } } - stats?.hp = res.hp - stats?.exp = res.exp - stats?.mp = res.mp - stats?.gp = res.gp - stats?.lvl = res.lvl - user.party?.quest?.progress?.up = (user.party?.quest?.progress?.up - ?: 0F) + (res._tmp?.quest?.progressDelta?.toFloat() ?: 0F) - user.stats = stats } + stats?.hp = res.hp + stats?.exp = res.exp + stats?.mp = res.mp + stats?.gp = res.gp + stats?.lvl = res.lvl + user.party?.quest?.progress?.up = (user.party?.quest?.progress?.up + ?: 0F) + (res._tmp?.quest?.progressDelta?.toFloat() ?: 0F) + user.stats = stats } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt index 733862d80..eab649202 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt @@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.models.tasks.RemindersItem import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.android.habitica.models.tasks.TaskList import com.habitrpg.android.habitica.models.tasks.TasksOrder +import com.habitrpg.android.habitica.models.user.User import io.reactivex.Flowable import io.reactivex.Maybe import io.realm.RealmResults @@ -33,4 +34,5 @@ interface TaskLocalRepository : BaseLocalRepository { fun updateTaskPositions(taskOrder: List) fun saveCompletedTodos(userId: String, tasks: MutableCollection) fun getErroredTasks(userID: String): Flowable> + fun getUser(userID: String): Flowable } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt index 12af5e247..343102b22 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt @@ -2,6 +2,7 @@ package com.habitrpg.android.habitica.data.local.implementation import com.habitrpg.android.habitica.data.local.TaskLocalRepository import com.habitrpg.android.habitica.models.tasks.* +import com.habitrpg.android.habitica.models.user.User import io.reactivex.Flowable import io.reactivex.Maybe import io.realm.Realm @@ -12,6 +13,9 @@ import io.realm.Sort class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), TaskLocalRepository { override fun getTasks(taskType: String, userID: String): Flowable> { + if (realm.isClosed) { + return Flowable.empty() + } return realm.where(Task::class.java) .equalTo("type", taskType) .equalTo("userId", userID) @@ -23,6 +27,9 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), } override fun getTasks(userId: String): Flowable> { + if (realm.isClosed) { + return Flowable.empty() + } return realm.where(Task::class.java).equalTo("userId", userId) .sort("position", Sort.ASCENDING, "dateCreated", Sort.DESCENDING) .findAll() @@ -210,4 +217,13 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), .asFlowable() .filter { it.isLoaded } .retry(1) } + + override fun getUser(userID: String): Flowable { + return realm.where(User::class.java) + .equalTo("id", userID) + .findAll() + .asFlowable() + .filter { realmObject -> realmObject.isLoaded && realmObject.isValid && !realmObject.isEmpty() } + .map { users -> users.first() } + } } 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 666e8729f..718266993 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 @@ -346,21 +346,15 @@ open class TaskRecyclerViewFragment : BaseFragment(), androidx.swiperefreshlayou when (fragment.classType) { Task.TYPE_HABIT -> { fragment.tutorialStepIdentifier = "habits" - tutorialTexts = Arrays.asList(context.getString(R.string.tutorial_overview), - context.getString(R.string.tutorial_habits_1), - context.getString(R.string.tutorial_habits_2), - context.getString(R.string.tutorial_habits_3), - context.getString(R.string.tutorial_habits_4)) + tutorialTexts = listOf(context.getString(R.string.tutorial_overview), context.getString(R.string.tutorial_habits_1), context.getString(R.string.tutorial_habits_2), context.getString(R.string.tutorial_habits_3), context.getString(R.string.tutorial_habits_4)) } Task.FREQUENCY_DAILY -> { fragment.tutorialStepIdentifier = "dailies" - tutorialTexts = Arrays.asList(context.getString(R.string.tutorial_dailies_1), - context.getString(R.string.tutorial_dailies_2)) + tutorialTexts = listOf(context.getString(R.string.tutorial_dailies_1), context.getString(R.string.tutorial_dailies_2)) } Task.TYPE_TODO -> { fragment.tutorialStepIdentifier = "todos" - tutorialTexts = Arrays.asList(context.getString(R.string.tutorial_todos_1), - context.getString(R.string.tutorial_todos_2)) + tutorialTexts = listOf(context.getString(R.string.tutorial_todos_1), context.getString(R.string.tutorial_todos_2)) } } } From de83f8741b81da6f7d5c4325507ee3d030acf98c Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 15:10:51 +0200 Subject: [PATCH 08/96] Fix issue with task filters --- .../android/habitica/ui/fragments/tasks/TasksFragment.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt index 617a8e282..c92c3bd08 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt @@ -46,7 +46,9 @@ class TasksFragment : BaseMainFragment() { } private val activeFragment: TaskRecyclerViewFragment? - get() = viewFragmentsDictionary?.get(viewPager?.currentItem) + get() { + return viewFragmentsDictionary?.get(viewPager?.currentItem) ?: (childFragmentManager.findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + viewPager?.currentItem) as? TaskRecyclerViewFragment) + } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { From 028f5c0d01b91dd85eb18f5a5091492007447862 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 5 Aug 2019 17:30:10 +0200 Subject: [PATCH 09/96] bump version number --- Habitica/build.gradle | 4 ++-- .../data/local/implementation/RealmBaseLocalRepository.kt | 6 ++++++ fastlane/changelog.txt | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 2364cc749..f2248cafb 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -149,8 +149,8 @@ android { buildConfigField "String", "TESTING_LEVEL", "\"production\"" multiDexEnabled true - versionCode 2174 - versionName "2.0.1" + versionCode 2179 + versionName "2.0.2" } lintOptions { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt index 1707d4c62..b414ec083 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt @@ -15,12 +15,14 @@ abstract class RealmBaseLocalRepository internal constructor(protected var realm } override fun executeTransaction(transaction: (Realm) -> Unit) { + if (isClosed) { return } realm.executeTransaction { transaction(it) } } override fun executeTransaction(transaction: Realm.Transaction) { + if (isClosed) { return } realm.executeTransaction(transaction) } @@ -33,18 +35,22 @@ abstract class RealmBaseLocalRepository internal constructor(protected var realm } override fun getUnmanagedCopy(list: List): List { + if (isClosed) { return emptyList() } return realm.copyFromRealm(list) } override fun save(`object`: T) { + if (isClosed) { return } realm.executeTransactionAsync { realm1 -> realm1.insertOrUpdate(`object`) } } override fun save(objects: List) { + if (isClosed) { return } realm.executeTransactionAsync { realm1 -> realm1.insertOrUpdate(objects) } } override fun saveSyncronous(`object`: T) { + if (isClosed) { return } realm.executeTransaction { realm1 -> realm1.insertOrUpdate(`object`) } } } diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt index 25bf9d3ed..e20bde78c 100644 --- a/fastlane/changelog.txt +++ b/fastlane/changelog.txt @@ -1,3 +1,3 @@ -We fixed a minor crash in version 2.0.1. +We fixed a bug where the task list would not update correctly in version 2.0.2. In the latest update, version 2.0 brings you a redesigned way to add new tasks as well as a new Notifications section in the Menu so that you can stay up to date with your Party and Guilds! We also fixed bugs related to task editing, Shops, and Rewards. Be sure to download this update now for a better Habitica experience! From 3915eeacbfc3b0ea9bbad5970f8194169b73050d Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 5 Aug 2019 17:31:20 +0200 Subject: [PATCH 10/96] Fix showing pin button. Fixes #1194 --- Habitica/res/layout/dialog_purchase_shopitem_header.xml | 7 ++++--- .../habitica/ui/fragments/inventory/shops/ShopFragment.kt | 2 +- .../android/habitica/ui/viewHolders/ShopItemViewHolder.kt | 4 ++-- .../android/habitica/ui/views/shops/PurchaseDialog.kt | 4 +++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Habitica/res/layout/dialog_purchase_shopitem_header.xml b/Habitica/res/layout/dialog_purchase_shopitem_header.xml index abc40722f..6c7dd1373 100644 --- a/Habitica/res/layout/dialog_purchase_shopitem_header.xml +++ b/Habitica/res/layout/dialog_purchase_shopitem_header.xml @@ -10,8 +10,8 @@