update survey
|
|
@ -149,7 +149,7 @@ android {
|
|||
buildConfigField "String", "TESTING_LEVEL", "\"production\""
|
||||
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
|
||||
|
||||
versionCode 2946
|
||||
versionCode 2950
|
||||
versionName "3.2.3"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 15 KiB |
|
|
@ -51,8 +51,10 @@
|
|||
android:gravity="center"
|
||||
style="@style/Body1"
|
||||
android:textSize="12sp"
|
||||
android:padding="7dp"
|
||||
android:paddingVertical="7dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="@color/brand_300"
|
||||
android:textColor="@color/white"
|
||||
android:visibility="gone"
|
||||
tools:text="Available until May 6"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -124,9 +124,13 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
|
|||
localRepository.getSpecialItems(user)
|
||||
|
||||
override fun useSkill(key: String, target: String?, taskId: String): Flowable<SkillResponse> {
|
||||
return zipWithLiveUser(apiClient.useSkill(key, target ?: "", taskId)) { skillResponse, user ->
|
||||
skillResponse.user?.let { mergeUser(user, it) }
|
||||
skillResponse
|
||||
return zipWithLiveUser(apiClient.useSkill(key, target ?: "", taskId)) { response, user ->
|
||||
response.hpDiff = response.user?.stats?.hp ?: 0 - (user.stats?.hp ?: 0.0)
|
||||
response.expDiff = response.user?.stats?.exp ?: 0 - (user.stats?.exp ?: 0.0)
|
||||
response.goldDiff = response.user?.stats?.gp ?: 0 - (user.stats?.gp ?: 0.0)
|
||||
response.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||
response.user?.let { mergeUser(user, it) }
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.habitrpg.android.habitica.interactors
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
|
@ -13,6 +14,7 @@ import com.habitrpg.android.habitica.models.user.Stats
|
|||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
|
@ -27,10 +29,6 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
|
|||
soundManager.loadAndPlayAudio(SoundManager.SoundLevelUp)
|
||||
|
||||
val suppressedModals = requestValues.user.preferences?.suppressModals
|
||||
if (suppressedModals?.levelUp == true) {
|
||||
showClassSelection(requestValues)
|
||||
return@defer Flowable.just<Stats>(requestValues.user.stats)
|
||||
}
|
||||
|
||||
if (requestValues.newLevel == 10) {
|
||||
val binding = DialogLevelup10Binding.inflate(requestValues.activity.layoutInflater)
|
||||
|
|
@ -52,6 +50,12 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
|
|||
alert.enqueue()
|
||||
}
|
||||
} else {
|
||||
if (suppressedModals?.levelUp == true) {
|
||||
HabiticaSnackbar.showSnackbar(requestValues.snackbarTargetView,
|
||||
requestValues.activity.getString(R.string.levelup_header, requestValues.newLevel),
|
||||
HabiticaSnackbar.SnackbarDisplayType.SUCCESS, true)
|
||||
return@defer Flowable.just<Stats>(requestValues.user.stats)
|
||||
}
|
||||
val customView = requestValues.activity.layoutInflater.inflate(R.layout.dialog_levelup, null)
|
||||
if (customView != null) {
|
||||
val dialogAvatarView = customView.findViewById<AvatarView>(R.id.avatarView)
|
||||
|
|
@ -90,7 +94,7 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
|
|||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
class RequestValues(val user: User, val level: Int?, val activity: AppCompatActivity) : UseCase.RequestValues {
|
||||
class RequestValues(val user: User, val level: Int?, val activity: AppCompatActivity, val snackbarTargetView: ViewGroup) : UseCase.RequestValues {
|
||||
val newLevel: Int = level ?: 0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ constructor(threadExecutor: ThreadExecutor, postExecutionThread: PostExecutionTh
|
|||
HabiticaSnackbar.showSnackbar(requestValues.snackbarTargetView, null, null, view, type)
|
||||
}
|
||||
if (requestValues.hasLeveledUp == true) {
|
||||
return@defer levelUpUseCase.observable(LevelUpUseCase.RequestValues(requestValues.user, requestValues.level, requestValues.context))
|
||||
return@defer levelUpUseCase.observable(LevelUpUseCase.RequestValues(requestValues.user, requestValues.level, requestValues.context, requestValues.snackbarTargetView))
|
||||
.flatMap { userRepository.retrieveUser(true) }
|
||||
.map { it.stats }
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class Survey2021Promotion : HabiticaPromotion(), HabiticaWebPromotion {
|
|||
override fun configurePromoMenuView(view: PromoMenuView) {
|
||||
val context = view.context
|
||||
view.canClose = true
|
||||
view.binding.closeButton.setColorFilter(ContextCompat.getColor(context, R.color.blue_100))
|
||||
view.setBackgroundColor(ContextCompat.getColor(context, R.color.blue_1))
|
||||
view.setTitleText(context.getString(R.string.survey_title))
|
||||
view.setSubtitleText(context.getString(R.string.survey_menu_description))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter
|
|||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.kotlin.combineLatest
|
||||
import io.realm.RealmResults
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
|
@ -138,10 +140,10 @@ class StableRecyclerFragment : BaseFragment<FragmentRecyclerviewBinding>() {
|
|||
} else {
|
||||
inventoryRepository.getMounts().firstElement()
|
||||
}
|
||||
val ownedObservable: Maybe<out Map<String, OwnedObject>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getOwnedPets().firstElement()
|
||||
val ownedObservable: Flowable<out Map<String, OwnedObject>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getOwnedPets()
|
||||
} else {
|
||||
inventoryRepository.getOwnedMounts().firstElement()
|
||||
inventoryRepository.getOwnedMounts()
|
||||
}.map {
|
||||
val animalMap = mutableMapOf<String, OwnedObject>()
|
||||
it.forEach { animal ->
|
||||
|
|
@ -162,9 +164,11 @@ class StableRecyclerFragment : BaseFragment<FragmentRecyclerviewBinding>() {
|
|||
.subscribe({
|
||||
adapter?.setEggs(it)
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(observable.zipWith(ownedObservable, { unsortedAnimals, ownedAnimals ->
|
||||
mapAnimals(unsortedAnimals, ownedAnimals)
|
||||
}).subscribe({ items -> adapter?.setItemList(items) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(ownedObservable.combineLatest(observable.toFlowable())
|
||||
.map { (ownedAnimals, unsortedAnimals) ->
|
||||
mapAnimals(unsortedAnimals, ownedAnimals)
|
||||
}
|
||||
.subscribe({ items -> adapter?.setItemList(items) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(inventoryRepository.getOwnedItems(true).subscribe({ adapter?.setOwnedItems(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(inventoryRepository.getMounts().subscribe({ adapter?.setExistingMounts(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(inventoryRepository.getOwnedMounts()
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class SkillTasksRecyclerViewFragment : BaseFragment<FragmentRecyclerviewBinding>
|
|||
super.onResume()
|
||||
|
||||
var tasks = taskRepository.getTasks(taskType ?: "", userId)
|
||||
tasks.map { it.where().isEmpty("challengeID").and().isNull("group").findAll() }
|
||||
if (taskType == Task.TYPE_TODO) {
|
||||
tasks = tasks.map { it.where().equalTo("completed", false).findAll() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentSkillsBinding
|
||||
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.Skill
|
||||
import com.habitrpg.android.habitica.models.responses.SkillResponse
|
||||
|
|
@ -20,12 +21,17 @@ import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity
|
|||
import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.SkillsRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengesOverviewFragmentDirections
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.Companion.showSnackbar
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
||||
|
||||
|
|
@ -125,11 +131,14 @@ class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
|||
}
|
||||
if (response.damage > 0) {
|
||||
context?.let {
|
||||
showSnackbar(activity.snackbarContainer, null,
|
||||
context?.getString(R.string.caused_damage),
|
||||
BitmapDrawable(resources, HabiticaIconsHelper.imageOfDamage()),
|
||||
ContextCompat.getColor(it, R.color.green_10), "+" + response.damage,
|
||||
HabiticaSnackbar.SnackbarDisplayType.SUCCESS)
|
||||
GlobalScope.launch(context = Dispatchers.Main) {
|
||||
delay(2000L)
|
||||
showSnackbar(activity.snackbarContainer, null,
|
||||
context?.getString(R.string.caused_damage),
|
||||
BitmapDrawable(resources, HabiticaIconsHelper.imageOfDamage()),
|
||||
ContextCompat.getColor(it, R.color.green_10), "+%.01f".format(response.damage),
|
||||
HabiticaSnackbar.SnackbarDisplayType.SUCCESS)
|
||||
}
|
||||
}
|
||||
}
|
||||
compositeSubscription.add(userRepository.retrieveUser(false).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
|
|
|
|||
|
|
@ -155,29 +155,29 @@ private constructor(parent: ViewGroup, content: View, callback: ContentViewCallb
|
|||
if (isCelebratory) {
|
||||
container.postDelayed({
|
||||
ParticleSystem(container, 30, ContextCompat.getDrawable(container.context, R.drawable.confetti_blue), 6000)
|
||||
.setAcceleration(0.00020f, 90)
|
||||
.setAcceleration(0.00070f, 90)
|
||||
.setRotationSpeed(144f)
|
||||
.setSpeedByComponentsRange(-0.15f, 0.15f, -0.15f, -0.45f)
|
||||
.setFadeOut(200, AccelerateInterpolator())
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 2000)
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 1000)
|
||||
ParticleSystem(container, 30, ContextCompat.getDrawable(container.context, R.drawable.confetti_red), 6000)
|
||||
.setAcceleration(0.00030f, 90)
|
||||
.setAcceleration(0.00060f, 90)
|
||||
.setRotationSpeed(144f)
|
||||
.setSpeedByComponentsRange(-0.15f, 0.15f, -0.15f, -0.45f)
|
||||
.setFadeOut(200, AccelerateInterpolator())
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 2000)
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 1000)
|
||||
ParticleSystem(container, 30, ContextCompat.getDrawable(container.context, R.drawable.confetti_yellow), 6000)
|
||||
.setAcceleration(0.00020f, 90)
|
||||
.setAcceleration(0.00070f, 90)
|
||||
.setRotationSpeed(144f)
|
||||
.setSpeedByComponentsRange(-0.15f, 0.15f, -0.15f, -0.45f)
|
||||
.setFadeOut(200, AccelerateInterpolator())
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 2000)
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 1000)
|
||||
ParticleSystem(container, 30, ContextCompat.getDrawable(container.context, R.drawable.confetti_purple), 6000)
|
||||
.setAcceleration(0.00030f, 90)
|
||||
.setAcceleration(0.00090f, 90)
|
||||
.setRotationSpeed(144f)
|
||||
.setSpeedByComponentsRange(-0.15f, 0.15f, -0.15f, -0.45f)
|
||||
.setFadeOut(200, AccelerateInterpolator())
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 2000)
|
||||
.emitWithGravity(container, Gravity.BOTTOM, 7, 1000)
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
if (shopItem.isTypeGear) {
|
||||
checkGearClass()
|
||||
}
|
||||
setLimitedTextView()
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
|
|
@ -445,15 +446,16 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
return@filter shouldWarn
|
||||
}.flatMap { inventoryRepository.getOwnedItems("eggs").firstElement() }
|
||||
} else if (item.purchaseType == "hatchingPotions") {
|
||||
totalCount = 18
|
||||
totalCount = if (item.path?.contains("wacky") == true) {
|
||||
// Wacky pets can't be raised to mounts, so only need half as many
|
||||
9
|
||||
} else {
|
||||
18
|
||||
}
|
||||
maybe = inventoryRepository.getPets().firstElement().filter {
|
||||
val filteredPets = it.filter {pet ->
|
||||
pet.type == "premium" || pet.type == "wacky"
|
||||
}
|
||||
if (it.firstOrNull()?.type == "wacky") {
|
||||
// Wacky pets can't be raised to mounts, so only need half as many
|
||||
totalCount = 9
|
||||
}
|
||||
shouldWarn = filteredPets.isNotEmpty()
|
||||
return@filter shouldWarn
|
||||
}.flatMap { inventoryRepository.getOwnedItems("hatchingPotions").firstElement() }
|
||||
|
|
@ -464,21 +466,21 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
if (!shouldWarn) {
|
||||
onResult(-1)
|
||||
}
|
||||
val remaining = 18 - ownedCount
|
||||
val remaining = totalCount - ownedCount
|
||||
onResult(max(0, remaining))
|
||||
}.flatMap {
|
||||
for (thisItem in it) {
|
||||
if (thisItem.key == item.key) {
|
||||
ownedCount += thisItem.numberOwned
|
||||
}
|
||||
}
|
||||
inventoryRepository.getOwnedMounts().firstElement() }
|
||||
.flatMapPublisher {
|
||||
for (mount in it) {
|
||||
if (mount.key?.contains(item.key) == true) {
|
||||
ownedCount += if (mount.owned) 1 else 0
|
||||
for (thisItem in it) {
|
||||
if (thisItem.key == item.key) {
|
||||
ownedCount += thisItem.numberOwned
|
||||
}
|
||||
}
|
||||
inventoryRepository.getOwnedMounts().firstElement()
|
||||
}.flatMapPublisher {
|
||||
for (mount in it) {
|
||||
if (mount.key?.contains(item.key) == true) {
|
||||
ownedCount += if (mount.owned) 1 else 0
|
||||
}
|
||||
}
|
||||
}
|
||||
inventoryRepository.getOwnedPets()
|
||||
}.firstElement().subscribe({
|
||||
for (pet in it) {
|
||||
|
|
|
|||