From 8caca96e41f382a5520ea7ffcb12dbe65503013b Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 8 Jul 2019 14:40:14 +0200 Subject: [PATCH] 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)) } } }