Merge pull request #1354 from Quazyrog/collection-quest-indication

Collection quest indication
This commit is contained in:
Phillip Thelen 2020-09-18 09:40:15 +02:00 committed by GitHub
commit e27b576a61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 86 additions and 18 deletions

View file

@ -147,6 +147,12 @@
android:orientation="vertical"
android:paddingStart="@dimen/spacing_large"
android:paddingEnd="@dimen/spacing_large"/>
<TextView
android:id="@+id/collectedItemsNumberView"
android:layout_width="match_parent"
android:gravity="end"
android:layout_height="wrap_content"
tools:text="+N items found"/>
<TextView
android:id="@+id/rageStrikeDescriptionView"
android:layout_width="match_parent"

View file

@ -36,4 +36,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<TextView
android:id="@+id/collectedItemsNumberView"
android:layout_width="match_parent"
android:gravity="end"
android:layout_height="wrap_content"
tools:text="+N items found"/>
</merge>

View file

@ -220,6 +220,7 @@
<string name="quests">Quêtes</string>
<string name="pets">Familiers</string>
<string name="mounts">Montures</string>
<string name="quest_items_found">Vous avez trouvé %d objets pour la quête</string>
<string name="armoireEquipment">Vous avez trouvé une pièce d\'équipement rare dans l\'Armoire : %s! Génial !</string>
<string name="armoireFood">Vous farfouillez dans l\'Armoire et trouvez une %1$s %2$s. Qu\'est-ce que ça fait là ?</string>
<string name="armoireExp">Vous luttez contre l\'Armoire et gagnez de l\'expérience. Prends ça !</string>

View file

@ -213,6 +213,7 @@
<string name="quests">Misje</string>
<string name="pets">Zwierzaki</string>
<string name="mounts">Wierzchowce</string>
<string name="quest_items_found">Znalazłeś %d przedmiot(y/ów) z zadania</string>
<string name="armoireEquipment">Znalazłeś element rzadkiego Ekwipunku w Skrzyni: %s! Super!</string>
<string name="armoireFood">Przeszukujesz Skrzynię i znajdujesz %1$s %2$s. Co to tam robi?</string>
<string name="armoireExp">Mocujesz się ze Skrzynią i zyskujesz Doświadczenie. A masz!</string>

View file

@ -271,6 +271,7 @@
<string name="pets">Pets</string>
<string name="mounts">Mounts</string>
<string name="quest_items_found">You\'ve found %d quest items</string>
<string name="armoireEquipment">You found %s in the Armoire</string>
<string name="armoireFood">You rummage in the Armoire and find %1$s %2$s. What\'s that doing in here?</string>
<string name="armoireExp">You wrestle with the Armoire and gain Experience. Take that!</string>

View file

@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.data
import com.habitrpg.android.habitica.data.local.UserQuestStatus
import com.habitrpg.android.habitica.models.Achievement
import com.habitrpg.android.habitica.models.QuestAchievement
import com.habitrpg.android.habitica.models.Skill
@ -77,5 +78,5 @@ interface UserRepository : BaseRepository {
fun getAchievements(): Flowable<RealmResults<Achievement>>
fun getQuestAchievements(): Flowable<RealmResults<QuestAchievement>>
fun getIsUserOnQuest(): Flowable<Boolean>
fun getUserQuestStatus(): Flowable<UserQuestStatus>
}

View file

@ -73,6 +73,7 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli
result.goldDelta = localData.gp - (stats?.gp ?: 0.0)
result.hasLeveledUp = localData.lvl > stats?.lvl ?: 0
result.questDamage = localData._tmp?.quest?.progressDelta
result.questItemsFound = localData._tmp?.quest?.collection
result.drop = localData._tmp?.drop
notifyFunc?.invoke(result)
@ -105,6 +106,7 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli
result.goldDelta = res.gp - (stats?.gp ?: 0.0)
result.hasLeveledUp = res.lvl > stats?.lvl ?: 0
result.questDamage = res._tmp?.quest?.progressDelta
result.questItemsFound = res._tmp?.quest?.collection
result.drop = res._tmp?.drop
if (localData == null) {
notifyFunc?.invoke(result)

View file

@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.data.TaskRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.data.local.UserLocalRepository
import com.habitrpg.android.habitica.data.local.UserQuestStatus
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.Achievement
@ -171,8 +172,8 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
}
override fun readNotification(id: String): Flowable<List<*>> = apiClient.readNotification(id)
override fun getIsUserOnQuest(): Flowable<Boolean> {
return localRepository.getIsUserOnQuest(userID)
override fun getUserQuestStatus(): Flowable<UserQuestStatus> {
return localRepository.getUserQuestStatus(userID)
}
override fun readNotifications(notificationIds: Map<String, List<String>>): Flowable<List<*>> =

View file

@ -9,6 +9,13 @@ import com.habitrpg.android.habitica.models.user.User
import io.reactivex.Flowable
import io.realm.RealmResults
enum class UserQuestStatus {
NO_QUEST,
QUEST_COLLECT,
QUEST_BOSS,
QUEST_UNKNOWN
}
interface UserLocalRepository : BaseLocalRepository {
fun getTutorialSteps(): Flowable<RealmResults<TutorialStep>>
@ -24,5 +31,5 @@ interface UserLocalRepository : BaseLocalRepository {
fun getSpecialItems(user: User): Flowable<RealmResults<Skill>>
fun getAchievements(): Flowable<RealmResults<Achievement>>
fun getQuestAchievements(userID: String): Flowable<RealmResults<QuestAchievement>>
fun getIsUserOnQuest(userID: String): Flowable<Boolean>
fun getUserQuestStatus(userID: String): Flowable<UserQuestStatus>
}

View file

@ -1,6 +1,7 @@
package com.habitrpg.android.habitica.data.local.implementation
import com.habitrpg.android.habitica.data.local.UserLocalRepository
import com.habitrpg.android.habitica.data.local.UserQuestStatus
import com.habitrpg.android.habitica.models.*
import com.habitrpg.android.habitica.models.social.ChallengeMembership
import com.habitrpg.android.habitica.models.social.ChatMessage
@ -13,7 +14,7 @@ import io.realm.Realm
import io.realm.RealmResults
class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), UserLocalRepository {
override fun getIsUserOnQuest(userID: String): Flowable<Boolean> {
override fun getUserQuestStatus(userID: String): Flowable<UserQuestStatus> {
return getUser(userID)
.map { it.party?.id ?: "" }
.filter { it.isNotBlank() }
@ -25,7 +26,12 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
.filter { groups -> groups.size > 0 }
.map { groups -> groups.first() }
}
.map { it.quest?.members?.find { questMember -> questMember.key == userID } != null }
.map { when {
it.quest?.members?.find { questMember -> questMember.key == userID } === null -> UserQuestStatus.NO_QUEST
it.quest?.progress?.collect?.isNotEmpty() ?: false -> UserQuestStatus.QUEST_COLLECT
it.quest?.progress?.hp ?: 0.0 > 0.0 -> UserQuestStatus.QUEST_BOSS
else -> UserQuestStatus.QUEST_UNKNOWN
}}
}
override fun getAchievements(): Flowable<RealmResults<Achievement>> {

View file

@ -1,14 +1,18 @@
package com.habitrpg.android.habitica.interactors
import android.content.Context
import android.os.Handler
import android.provider.Settings.Global.getString
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.executors.PostExecutionThread
import com.habitrpg.android.habitica.executors.ThreadExecutor
import com.habitrpg.android.habitica.helpers.SoundManager
import com.habitrpg.android.habitica.models.responses.TaskScoringResult
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import io.reactivex.Flowable
import java.lang.StringBuilder
import javax.inject.Inject
class DisplayItemDropUseCase @Inject
@ -17,11 +21,18 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
override fun buildUseCaseObservable(requestValues: RequestValues): Flowable<Void> {
return Flowable.defer {
val data = requestValues.data
var snackbarText = StringBuilder(data?.drop?.dialog ?: "")
if (data?.drop != null) {
if (data?.questItemsFound ?: 0 > 0 && requestValues.showQuestItems) {
if (snackbarText.isNotEmpty())
snackbarText.append('\n')
snackbarText.append(requestValues.context.getString(R.string.quest_items_found, data!!.questItemsFound))
}
if (snackbarText.isNotEmpty()) {
Handler().postDelayed({
HabiticaSnackbar.showSnackbar(requestValues.snackbarTargetView,
data.drop?.dialog, HabiticaSnackbar.SnackbarDisplayType.DROP)
snackbarText, HabiticaSnackbar.SnackbarDisplayType.DROP)
soundManager.loadAndPlayAudio(SoundManager.SoundItemDrop)
}, 3000L)
}
@ -30,5 +41,5 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
}
}
class RequestValues(val data: TaskScoringResult?, val context: AppCompatActivity, val snackbarTargetView: ViewGroup) : UseCase.RequestValues
class RequestValues(val data: TaskScoringResult?, val context: AppCompatActivity, val snackbarTargetView: ViewGroup, val showQuestItems: Boolean) : UseCase.RequestValues
}

View file

@ -11,6 +11,7 @@ open class QuestProgress : RealmObject() {
var key: String? = null
var hp: Double = 0.0
var rage: Double = 0.0
var collectedItems: Int = 0
var collect: RealmList<QuestProgressCollect>? = null
var down: Float = 0.0f
var up: Float = 0.0f

View file

@ -9,6 +9,7 @@ class TaskDirectionDataTemp {
class TaskDirectionDataQuest {
var progressDelta: Double = 0.0
var collection: Int = 0
}
class TaskDirectionDataDrop {

View file

@ -9,4 +9,5 @@ class TaskScoringResult {
var manaDelta: Double? = null
var hasLeveledUp: Boolean = false
var questDamage: Double? = null
var questItemsFound: Int? = null
}

View file

@ -33,6 +33,7 @@ import com.habitrpg.android.habitica.api.HostConfig
import com.habitrpg.android.habitica.api.MaintenanceApiService
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.*
import com.habitrpg.android.habitica.data.local.UserQuestStatus
import com.habitrpg.android.habitica.databinding.ActivityMainBinding
import com.habitrpg.android.habitica.events.*
import com.habitrpg.android.habitica.events.commands.FeedCommand
@ -80,7 +81,6 @@ import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
@ -134,7 +134,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
private var drawerFragment: NavigationDrawerFragment? = null
var drawerToggle: ActionBarDrawerToggle? = null
private var resumeFromActivity = false
private var userIsOnQuest = false
private var userQuestStatus = UserQuestStatus.NO_QUEST
val userID: String
get() = user?.id ?: ""
@ -180,9 +180,9 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
this@MainActivity.user = newUser
this@MainActivity.setUserData()
}, RxErrorHandler.handleEmptyError()))
compositeSubscription.add(userRepository.getIsUserOnQuest().subscribeWithErrorHandler {
userIsOnQuest = it
})
compositeSubscription.add(userRepository.getUserQuestStatus().subscribeWithErrorHandler(Consumer {
userQuestStatus = it
}))
val viewModel = ViewModelProvider(this).get(NotificationsViewModel::class.java)
notificationsViewModel = viewModel
@ -527,13 +527,23 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
internal fun displayTaskScoringResponse(data: TaskScoringResult?) {
if (user != null && data != null) {
val damageValue = when (userQuestStatus) {
UserQuestStatus.QUEST_BOSS,
UserQuestStatus.QUEST_UNKNOWN -> data.questDamage
else -> 0.0
}
compositeSubscription.add(notifyUserUseCase.observable(NotifyUserUseCase.RequestValues(this, snackbarContainer,
user, data.experienceDelta, data.healthDelta, data.goldDelta, data.manaDelta, if (userIsOnQuest) data.questDamage else 0.0, data.hasLeveledUp))
.subscribe({ }, RxErrorHandler.handleEmptyError()))
user, data.experienceDelta, data.healthDelta, data.goldDelta, data.manaDelta, damageValue, data.hasLeveledUp))
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
}
compositeSubscription.add(displayItemDropUseCase.observable(DisplayItemDropUseCase.RequestValues(data, this, snackbarContainer))
.subscribe({ }, RxErrorHandler.handleEmptyError()))
val showItemsFound = when (userQuestStatus) {
UserQuestStatus.QUEST_COLLECT,
UserQuestStatus.QUEST_UNKNOWN -> true
else -> false
}
compositeSubscription.add(displayItemDropUseCase.observable(DisplayItemDropUseCase.RequestValues(data, this, snackbarContainer, showItemsFound))
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
}

View file

@ -76,10 +76,12 @@ class OldQuestProgressView : LinearLayout {
}
binding.bossNameView.visibility = View.VISIBLE
binding.bossHealthView.visibility = View.VISIBLE
binding.collectedItemsNumberView.visibility = View.GONE
} else {
binding.bossNameView.visibility = View.GONE
binding.bossHealthView.visibility = View.GONE
binding.bossRageView.visibility = View.GONE
binding.collectedItemsNumberView.visibility = View.VISIBLE
if (progress != null) {
val inflater = LayoutInflater.from(context)
@ -101,14 +103,17 @@ class OldQuestProgressView : LinearLayout {
fun configure(user: User, userOnQuest: Boolean?) {
val value = (user.party?.quest?.progress?.up ?: 0F).toDouble()
val collectedItems = user.party?.quest?.progress?.collectedItems
if (userOnQuest == true) {
binding.bossHealthView.pendingValue = value
binding.bossHealthView.description = String.format("%.01f dmg pending", value)
binding.bossHealthView.descriptionIconVisibility = View.VISIBLE
binding.collectedItemsNumberView.text = context.getString(R.string.quest_items_found, collectedItems)
} else {
binding.bossHealthView.pendingValue = 0.0
binding.bossHealthView.description = ""
binding.bossHealthView.descriptionIconVisibility = View.GONE
binding.collectedItemsNumberView.text = ""
}
}

View file

@ -119,6 +119,7 @@ class QuestProgressView : LinearLayout {
binding.bossNameView.visibility = View.VISIBLE
binding.bossHealthView.visibility = View.VISIBLE
binding.bossHealthView.set(progress.progress?.hp ?: 0.0, quest.boss?.hp?.toDouble() ?: 0.0)
binding.collectedItemsNumberView.visibility = View.GONE
if (quest.boss?.hasRage() == true) {
binding.rageMeterView.visibility = View.VISIBLE
@ -141,6 +142,7 @@ class QuestProgressView : LinearLayout {
binding.rageMeterView.visibility = View.GONE
binding.bossRageView.visibility = View.GONE
binding.rageStrikeDescriptionView.visibility = View.GONE
binding.collectedItemsNumberView.visibility = View.VISIBLE
val collection = progress.progress?.collect
if (collection != null) {
@ -168,6 +170,8 @@ class QuestProgressView : LinearLayout {
fun configure(user: User) {
binding.pendingDamageTextView.text = String.format("%.01f dmg pending", (user.party?.quest?.progress?.up ?: 0F) )
val collectedItems = user.party?.quest?.progress?.collectedItems ?: 0
binding.collectedItemsNumberView.text = context.getString(R.string.quest_items_found, collectedItems)
}
private fun setupRageStrikeViews() {

View file

@ -33,6 +33,9 @@ class QuestDeserializer : JsonDeserializer<Quest> {
if (progressObj.has("down")) {
progress.down = progressObj.get("down").asFloat
}
if (progressObj.has("collectedItems")) {
progress.collectedItems = progressObj.get("collectedItems").asInt
}
if (progressObj.has("collect")) {
progress.collect = RealmList()
for ((key, value) in progressObj.getAsJsonObject("collect").entrySet()) {