mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-24 22:55:59 +00:00
customization improvements
This commit is contained in:
parent
01f0ac5a4a
commit
8eff8c6a5a
12 changed files with 81 additions and 91 deletions
|
|
@ -155,7 +155,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 2394
|
||||
versionCode 2396
|
||||
versionName "2.5"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,11 +104,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/avatar_animal_ears_view"
|
||||
android:visibility="gone"
|
||||
app:equipmentTitle="@string/animal_ears"/>
|
||||
<com.habitrpg.android.habitica.ui.views.EquipmentItemRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/avatar_animal_tail_view"
|
||||
android:visibility="gone"
|
||||
app:equipmentTitle="@string/animal_tail"/>
|
||||
<com.habitrpg.android.habitica.ui.views.EquipmentItemRow
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli
|
|||
}
|
||||
res._tmp?.drop?.key?.let { key ->
|
||||
val type = when(res._tmp?.drop?.type?.toLowerCase(Locale.US)) {
|
||||
"hatchingPotion" -> "hatchingPotions"
|
||||
"hatchingpotion" -> "hatchingPotions"
|
||||
"egg" -> "eggs"
|
||||
else -> res._tmp?.drop?.type?.toLowerCase(Locale.US)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,10 @@ class RealmCustomizationLocalRepository(realm: Realm) : RealmContentLocalReposit
|
|||
.isNull("availableFrom")
|
||||
.isNull("availableUntil")
|
||||
.endGroup()
|
||||
.or()
|
||||
.equalTo("purchased", true)
|
||||
.endGroup()
|
||||
}
|
||||
return query
|
||||
.sort("customizationSet")
|
||||
.sort("customizationSetName")
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.filter { it.isLoaded }
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ open class Customization : RealmObject() {
|
|||
var customizationSet: String? = null
|
||||
var customizationSetName: String? = null
|
||||
var text: String? = null
|
||||
var purchased = false
|
||||
var isBuyable = false
|
||||
var price: Int? = null
|
||||
var setPrice: Int? = null
|
||||
|
|
@ -48,7 +47,7 @@ open class Customization : RealmObject() {
|
|||
|
||||
fun getIconName(userSize: String?, hairColor: String?): String {
|
||||
return if (type == "background") {
|
||||
"background_$identifier"
|
||||
"icon_background_$identifier"
|
||||
} else {
|
||||
getImageName(userSize, hairColor)
|
||||
}
|
||||
|
|
@ -73,8 +72,9 @@ open class Customization : RealmObject() {
|
|||
return ""
|
||||
}
|
||||
|
||||
val isUsable: Boolean
|
||||
get() = price == null || price == 0 || purchased
|
||||
fun isUsable(purchased: Boolean): Boolean {
|
||||
return price == null || price == 0 || purchased
|
||||
}
|
||||
|
||||
val path: String
|
||||
get() {
|
||||
|
|
@ -82,8 +82,7 @@ open class Customization : RealmObject() {
|
|||
if (this.category != null) {
|
||||
path = path + "." + this.category
|
||||
}
|
||||
path = path + "." + identifier
|
||||
path = "$path.$identifier"
|
||||
return path
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.habitrpg.android.habitica.models.user
|
||||
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
open class OwnedCustomization : RealmObject(), OwnedObject {
|
||||
|
||||
@PrimaryKey
|
||||
override var combinedKey: String? = null
|
||||
override var userID: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
combinedKey = field + type + key
|
||||
}
|
||||
override var key: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
combinedKey = userID + type + field
|
||||
}
|
||||
|
||||
var type: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
combinedKey = userID + field + key
|
||||
}
|
||||
var category: String? = null
|
||||
var purchased = false
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
package com.habitrpg.android.habitica.models.user;
|
||||
|
||||
import com.habitrpg.android.habitica.models.inventory.Customization;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.realm.RealmList;
|
||||
|
|
@ -13,15 +11,15 @@ public class Purchases extends RealmObject {
|
|||
@PrimaryKey
|
||||
private String userId;
|
||||
|
||||
public RealmList<Customization> customizations;
|
||||
public RealmList<OwnedCustomization> customizations;
|
||||
User user;
|
||||
private SubscriptionPlan plan;
|
||||
|
||||
public List<Customization> getCustomizations() {
|
||||
public List<OwnedCustomization> getCustomizations() {
|
||||
return customizations;
|
||||
}
|
||||
|
||||
public void setCustomizations(RealmList<Customization> customizations) {
|
||||
public void setCustomizations(RealmList<OwnedCustomization> customizations) {
|
||||
this.customizations = customizations;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,20 +42,15 @@ class CustomizationRecyclerViewAdapter : androidx.recyclerview.widget.RecyclerVi
|
|||
this.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
var ownedCustomiztations: List<String> = listOf()
|
||||
|
||||
private val selectCustomizationEvents = PublishSubject.create<Customization>()
|
||||
private val unlockCustomizationEvents = PublishSubject.create<Customization>()
|
||||
private val unlockSetEvents = PublishSubject.create<CustomizationSet>()
|
||||
|
||||
fun updateOwnership(ownedCustomizations: List<String>) {
|
||||
for ((position, obj) in customizationList.withIndex()) {
|
||||
if (obj.javaClass == Customization::class.java) {
|
||||
val customization = obj as? Customization ?: return
|
||||
if (customization.purchased != ownedCustomizations.contains(customization.id)) {
|
||||
customization.purchased = ownedCustomizations.contains(customization.id)
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.ownedCustomiztations = ownedCustomizations
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder {
|
||||
|
|
@ -103,12 +98,12 @@ class CustomizationRecyclerViewAdapter : androidx.recyclerview.widget.RecyclerVi
|
|||
set.identifier = customization.customizationSet
|
||||
set.text = customization.customizationSetName
|
||||
set.price = customization.setPrice
|
||||
set.hasPurchasable = !customization.isUsable
|
||||
set.hasPurchasable = !customization.isUsable(ownedCustomiztations.contains(customization.identifier))
|
||||
lastSet = set
|
||||
customizationList.add(set)
|
||||
}
|
||||
customizationList.add(customization)
|
||||
if (!customization.isUsable && !lastSet.hasPurchasable) {
|
||||
if (!customization.isUsable(ownedCustomiztations.contains(customization.identifier)) && !lastSet.hasPurchasable) {
|
||||
lastSet.hasPurchasable = true
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +143,7 @@ class CustomizationRecyclerViewAdapter : androidx.recyclerview.widget.RecyclerVi
|
|||
binding.imageView.layoutParams = params
|
||||
}
|
||||
|
||||
if (customization.isUsable) {
|
||||
if (customization.isUsable(ownedCustomiztations.contains(customization.identifier))) {
|
||||
binding.buyButton.visibility = View.GONE
|
||||
} else {
|
||||
binding.buyButton.visibility = View.VISIBLE
|
||||
|
|
@ -168,7 +163,7 @@ class CustomizationRecyclerViewAdapter : androidx.recyclerview.widget.RecyclerVi
|
|||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
if (customization?.isUsable == false) {
|
||||
if (customization?.isUsable(ownedCustomiztations.contains(customization?.identifier)) == false) {
|
||||
if (customization?.customizationSet?.contains("timeTravel") == true) {
|
||||
val dialog = HabiticaAlertDialog(itemView.context)
|
||||
dialog.setMessage(R.string.purchase_from_timetravel_shop)
|
||||
|
|
@ -256,11 +251,11 @@ class CustomizationRecyclerViewAdapter : androidx.recyclerview.widget.RecyclerVi
|
|||
customizationList
|
||||
.filter { Customization::class.java.isAssignableFrom(it.javaClass) }
|
||||
.map { it as Customization }
|
||||
.filter { !it.isUsable && it.customizationSet != null && it.customizationSet == set?.identifier }
|
||||
.filter { !it.isUsable(ownedCustomiztations.contains(it.identifier)) && it.customizationSet != null && it.customizationSet == set?.identifier }
|
||||
.forEach { set?.customizations?.add(it) }
|
||||
if (additionalSetItems.isNotEmpty()) {
|
||||
additionalSetItems
|
||||
.filter { !it.isUsable && it.customizationSet != null && it.customizationSet == set?.identifier }
|
||||
.filter { !it.isUsable(ownedCustomiztations.contains(it.identifier)) && it.customizationSet != null && it.customizationSet == set?.identifier }
|
||||
.forEach { set?.customizations?.add(it) }
|
||||
}
|
||||
set?.let {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class AvatarCustomizationFragment : BaseMainFragment() {
|
|||
this.updateActiveCustomization(user)
|
||||
if (adapter.customizationList.size != 0) {
|
||||
val ownedCustomizations = ArrayList<String>()
|
||||
user.purchased?.customizations?.filter { it.type == this.type }?.mapTo(ownedCustomizations) { it.id ?: "" }
|
||||
user.purchased?.customizations?.filter { it.type == this.type && it.purchased }?.mapTo(ownedCustomizations) { it.key ?: "" }
|
||||
adapter.updateOwnership(ownedCustomizations)
|
||||
} else {
|
||||
this.loadCustomizations()
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ object DataBindingUtils {
|
|||
tempMap["Mount_Body_Gryphon-Gryphatrice"] = "gif"
|
||||
tempMap["background_clocktower"] = "gif"
|
||||
tempMap["background_airship"] = "gif"
|
||||
tempMap["background_steamwork"] = "gif"
|
||||
tempMap["Pet_HatchingPotion_Veggie"] = "gif"
|
||||
tempMap["Pet_HatchingPotion_Dessert"] = "gif"
|
||||
tempMap["Pet-HatchingPotion-Dessert"] = "gif"
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@ class CustomizationDeserializer : JsonDeserializer<List<Customization>> {
|
|||
val customizations = RealmList<Customization>()
|
||||
val realm = Realm.getDefaultInstance()
|
||||
|
||||
val existingCustomizations = realm.copyFromRealm(realm.where(Customization::class.java).findAll())
|
||||
if (jsonObject.has("shirt")) {
|
||||
val existingCustomizations = realm.copyFromRealm(realm.where(Customization::class.java).findAll())
|
||||
|
||||
for (customization in existingCustomizations) {
|
||||
if (jsonObject.has(customization.type)) {
|
||||
var nestedObject = jsonObject.get(customization.type).asJsonObject
|
||||
|
|
@ -48,8 +47,6 @@ class CustomizationDeserializer : JsonDeserializer<List<Customization>> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
val existingCustomizations = realm.copyFromRealm(realm.where(Customization::class.java).findAll())
|
||||
|
||||
for (customization in existingCustomizations) {
|
||||
if (jsonObject.has(customization.customizationSet)) {
|
||||
val nestedObject = jsonObject.get(customization.customizationSet).asJsonObject
|
||||
|
|
@ -123,19 +120,23 @@ class CustomizationDeserializer : JsonDeserializer<List<Customization>> {
|
|||
customization.type = "background"
|
||||
customization.identifier = key
|
||||
}
|
||||
if ("incentiveBackgrounds" == setName) {
|
||||
customization.customizationSetName = "Login Incentive"
|
||||
customization.price = 0
|
||||
customization.setPrice = 0
|
||||
customization.isBuyable = false
|
||||
} else if ("timeTravelBackgrounds" == setName) {
|
||||
customization.customizationSetName = "Time Travel Backgrounds"
|
||||
customization.price = 1
|
||||
customization.setPrice = 0
|
||||
customization.isBuyable = false
|
||||
} else {
|
||||
customization.price = 7
|
||||
customization.setPrice = 15
|
||||
when (setName) {
|
||||
"incentiveBackgrounds" -> {
|
||||
customization.customizationSetName = "Login Incentive"
|
||||
customization.price = 0
|
||||
customization.setPrice = 0
|
||||
customization.isBuyable = false
|
||||
}
|
||||
"timeTravelBackgrounds" -> {
|
||||
customization.customizationSetName = "Time Travel Backgrounds"
|
||||
customization.price = 1
|
||||
customization.setPrice = 0
|
||||
customization.isBuyable = false
|
||||
}
|
||||
else -> {
|
||||
customization.price = 7
|
||||
customization.setPrice = 15
|
||||
}
|
||||
}
|
||||
|
||||
customization.text = entry.get("text").asString
|
||||
|
|
|
|||
|
|
@ -5,17 +5,14 @@ import com.google.gson.JsonDeserializer;
|
|||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.habitrpg.android.habitica.models.inventory.Customization;
|
||||
import com.habitrpg.android.habitica.models.user.OwnedCustomization;
|
||||
import com.habitrpg.android.habitica.models.user.Purchases;
|
||||
import com.habitrpg.android.habitica.models.user.SubscriptionPlan;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.realm.Realm;
|
||||
import io.realm.RealmList;
|
||||
|
||||
public class PurchasedDeserializer implements JsonDeserializer<Purchases> {
|
||||
|
|
@ -23,47 +20,21 @@ public class PurchasedDeserializer implements JsonDeserializer<Purchases> {
|
|||
@Override
|
||||
public Purchases deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
RealmList<Customization> customizations = new RealmList<>();
|
||||
RealmList<OwnedCustomization> customizations = new RealmList<>();
|
||||
Purchases purchases = new Purchases();
|
||||
|
||||
List<Customization> existingCustomizations;
|
||||
try {
|
||||
Realm realm = Realm.getDefaultInstance();
|
||||
existingCustomizations = realm.copyFromRealm(realm.where(Customization.class).findAll());
|
||||
realm.close();
|
||||
} catch (RuntimeException e) {
|
||||
//Tests don't have a database
|
||||
existingCustomizations = new ArrayList<>();
|
||||
}
|
||||
for (Customization customization : existingCustomizations) {
|
||||
if (object.has(customization.getType())) {
|
||||
JsonObject nestedObject = object.get(customization.getType()).getAsJsonObject();
|
||||
if (customization.getCategory() != null) {
|
||||
if (nestedObject.has(customization.getCategory())) {
|
||||
nestedObject = nestedObject.get(customization.getCategory()).getAsJsonObject();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nestedObject.has(customization.getIdentifier())) {
|
||||
customizations.add(this.parseCustomization(customization, customization.getType(), customization.getCategory(), customization.getIdentifier(), nestedObject.get(customization.getIdentifier()).getAsBoolean()));
|
||||
nestedObject.remove(customization.getIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String type : Arrays.asList("background", "shirt", "skin")) {
|
||||
if (!object.has(type)) {
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, JsonElement> entry : object.get(type).getAsJsonObject().entrySet()) {
|
||||
customizations.add(this.parseCustomization(null, type, null, entry.getKey(), entry.getValue().getAsBoolean()));
|
||||
customizations.add(this.parseCustomization(type, null, entry.getKey(), entry.getValue().getAsBoolean()));
|
||||
}
|
||||
}
|
||||
if (object.has("hair")) {
|
||||
for (Map.Entry<String, JsonElement> categoryEntry : object.get("hair").getAsJsonObject().entrySet()) {
|
||||
for (Map.Entry<String, JsonElement> entry : categoryEntry.getValue().getAsJsonObject().entrySet()) {
|
||||
customizations.add(this.parseCustomization(null, "hair", categoryEntry.getKey(), entry.getKey(), entry.getValue().getAsBoolean()));
|
||||
customizations.add(this.parseCustomization("hair", categoryEntry.getKey(), entry.getKey(), entry.getValue().getAsBoolean()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,15 +45,12 @@ public class PurchasedDeserializer implements JsonDeserializer<Purchases> {
|
|||
return purchases;
|
||||
}
|
||||
|
||||
private Customization parseCustomization(Customization existingCustomizaion, String type, String category, String key, boolean wasPurchased) {
|
||||
Customization customization = existingCustomizaion;
|
||||
if (customization == null) {
|
||||
customization = new Customization();
|
||||
customization.setIdentifier(key);
|
||||
customization.setType(type);
|
||||
if (category != null) {
|
||||
customization.setCategory(category);
|
||||
}
|
||||
private OwnedCustomization parseCustomization(String type, String category, String key, boolean wasPurchased) {
|
||||
OwnedCustomization customization = new OwnedCustomization();
|
||||
customization.setKey(key);
|
||||
customization.setType(type);
|
||||
if (category != null) {
|
||||
customization.setCategory(category);
|
||||
}
|
||||
customization.setPurchased(wasPurchased);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue