diff --git a/Habitica/res/layout/activity_gem_purchase.xml b/Habitica/res/layout/activity_gem_purchase.xml index 4c0e82efc..b85ada1cc 100644 --- a/Habitica/res/layout/activity_gem_purchase.xml +++ b/Habitica/res/layout/activity_gem_purchase.xml @@ -20,7 +20,7 @@ tools:context=".ui.activities.MainActivity"> diff --git a/Habitica/res/layout/fragment_challengeslist.xml b/Habitica/res/layout/fragment_challengeslist.xml index c95d0f2b5..f4241301f 100644 --- a/Habitica/res/layout/fragment_challengeslist.xml +++ b/Habitica/res/layout/fragment_challengeslist.xml @@ -18,7 +18,7 @@ android:scrollbars="vertical" android:paddingBottom="?attr/actionBarSize" /> \ No newline at end of file + android:id="@+id/viewPager" /> \ No newline at end of file diff --git a/Habitica/res/layout/fragment_items.xml b/Habitica/res/layout/fragment_items.xml index af58a500a..7d4c7d618 100644 --- a/Habitica/res/layout/fragment_items.xml +++ b/Habitica/res/layout/fragment_items.xml @@ -44,7 +44,7 @@ android:layout_marginBottom="8dp"/> diff --git a/Habitica/res/layout/fragment_refresh_recyclerview.xml b/Habitica/res/layout/fragment_refresh_recyclerview.xml index 89b961273..411cab653 100644 --- a/Habitica/res/layout/fragment_refresh_recyclerview.xml +++ b/Habitica/res/layout/fragment_refresh_recyclerview.xml @@ -22,7 +22,7 @@ android:paddingBottom="?attr/actionBarSize" /> \ No newline at end of file + android:id="@+id/viewPager" /> \ No newline at end of file diff --git a/Habitica/res/layout/shop_header.xml b/Habitica/res/layout/shop_header.xml index e1b930ac4..524855a71 100644 --- a/Habitica/res/layout/shop_header.xml +++ b/Habitica/res/layout/shop_header.xml @@ -21,7 +21,7 @@ android:background="@drawable/gradient_white"/> + \ No newline at end of file diff --git a/Habitica/res/layout/simple_textview.xml b/Habitica/res/layout/simple_textview.xml index 1b65be843..71790944d 100644 --- a/Habitica/res/layout/simple_textview.xml +++ b/Habitica/res/layout/simple_textview.xml @@ -1,10 +1,12 @@ - - + + android:textSize="15sp"/> - - \ No newline at end of file + \ No newline at end of file diff --git a/Habitica/res/layout/widget_task_list.xml b/Habitica/res/layout/widget_task_list.xml index 8077516cf..f33c97d3c 100644 --- a/Habitica/res/layout/widget_task_list.xml +++ b/Habitica/res/layout/widget_task_list.xml @@ -23,7 +23,7 @@ android:background="@color/widget_background" /> Assigns more points to the attributes important to your Class. Assigns points based on the Strength, Intelligence, Constitution, and Perception categories associated with the tasks you complete. Allocating Points + Class Equipment + You already have all equipment! More will be released during the Grand Galas, near the solstices and equinoxes. diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java index a3633d5a7..ca7534c38 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java @@ -273,7 +273,9 @@ public interface ApiService { Observable> postPrivateMessage(@Body Map messageDetails); @GET("shops/{identifier}") - Observable> fetchShopInventory(@Path("identifier") String identifier); + Observable> retrieveShopInventory(@Path("identifier") String identifier); + @GET("shops/market-gear") + Observable> retrieveMarketGear(); //Push notifications @POST("user/push-devices") diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.java b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.java index d6bb7d381..b0bc801fc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.java @@ -188,7 +188,7 @@ public interface ApiClient { Observable postPrivateMessage(Map messageDetails); - Observable fetchShopInventory(String identifier); + Observable retrieveShopIventory(String identifier); //Push notifications Observable> addPushDevice(Map pushDeviceData); @@ -251,4 +251,6 @@ public interface ApiClient { Observable allocatePoint(String stat); Observable bulkAllocatePoints(int strength, int intelligence, int constitution, int perception); + + Observable retrieveMarketGear(); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.java b/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.java index e3d966059..cd37ae918 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.java @@ -75,7 +75,8 @@ public interface InventoryRepository extends ContentRepository { Observable buyItem(User user, String id, double value); - Observable fetchShopInventory(String identifier); + Observable retrieveShopInventory(String identifier); + Observable retrieveMarketGear(); Observable purchaseMysterySet(String categoryIdentifier); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java index 6be940598..ddcbbed63 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java @@ -850,8 +850,8 @@ public class ApiClientImpl implements Action1, ApiClient { } @Override - public Observable fetchShopInventory(String identifier) { - return apiService.fetchShopInventory(identifier).compose(configureApiCallObserver()); + public Observable retrieveShopIventory(String identifier) { + return apiService.retrieveShopInventory(identifier).compose(configureApiCallObserver()); } @Override @@ -998,4 +998,9 @@ public class ApiClientImpl implements Action1, ApiClient { stats.put("per", perception); return apiService.bulkAllocatePoints(stats).compose(configureApiCallObserver()); } + + @Override + public Observable retrieveMarketGear() { + return apiService.retrieveMarketGear().compose(configureApiCallObserver()); + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.java b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.java index d2c366736..87d3d39ad 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.java @@ -68,7 +68,7 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl { List itemKeys = new ArrayList<>(); for (ShopItem item : items) { - itemKeys.add(item.key); + itemKeys.add(item.getKey()); } itemKeys.add("potion"); itemKeys.add("armoire"); @@ -80,17 +80,17 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl fetchShopInventory(String identifier) { - return apiClient.fetchShopInventory(identifier); + public Observable retrieveShopInventory(String identifier) { + return apiClient.retrieveShopIventory(identifier); + } + + @Override + public Observable retrieveMarketGear() { + return apiClient.retrieveMarketGear(); } @Override @@ -332,7 +337,7 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl retrieveInAppRewards()); } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewHolder-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewHolder-Extensions.kt new file mode 100644 index 000000000..d5f91ad08 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ViewHolder-Extensions.kt @@ -0,0 +1,9 @@ +package com.habitrpg.android.habitica.extensions + +import android.support.annotation.IdRes +import android.view.View + +fun bindView(container: View, @IdRes res: Int) : Lazy { + @Suppress("UNCHECKED_CAST") + return lazy(LazyThreadSafetyMode.NONE) { container.findViewById(res) } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.java deleted file mode 100644 index 2321e5603..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.habitrpg.android.habitica.models.shops; - -import android.content.Context; - -import com.habitrpg.android.habitica.R; - -import java.util.List; - -public class Shop { - - public static final String MARKET = "market"; - public static final String QUEST_SHOP = "questShop"; - public static final String TIME_TRAVELERS_SHOP = "timeTravelersShop"; - public static final String SEASONAL_SHOP = "seasonalShop"; - public String identifier; - public String text; - public String notes; - public String imageName; - - public List categories; - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getNotes() { - return notes; - } - - public void setNotes(String notes) { - this.notes = notes; - } - - public String getImageName() { - return imageName; - } - - public void setImageName(String imageName) { - this.imageName = imageName; - } - - public List getCategories() { - return categories; - } - - public void setCategories(List categories) { - this.categories = categories; - } - - public int getNpcNameResource() { - switch (getIdentifier()) { - case "market": - return R.string.market_owner; - case "questShop": - return R.string.questShop_owner; - case "seasonalShop": - return R.string.seasonalShop_owner; - case "timeTravelersShop": - return R.string.timetravelers_owner; - default: - return R.string.market_owner; - } - } - - public String getNpcName(Context context) { - return context.getString(getNpcNameResource()); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.kt new file mode 100644 index 000000000..e26773221 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/Shop.kt @@ -0,0 +1,32 @@ +package com.habitrpg.android.habitica.models.shops + +import android.content.Context + +import com.habitrpg.android.habitica.R + +class Shop { + var identifier: String = "" + var text: String = "" + var notes: String = "" + var imageName: String = "" + + var categories: MutableList = ArrayList() + + val npcNameResource: Int + get() = when (identifier) { + MARKET -> R.string.market_owner + QUEST_SHOP -> R.string.questShop_owner + SEASONAL_SHOP -> R.string.seasonalShop_owner + TIME_TRAVELERS_SHOP -> R.string.timetravelers_owner + else -> R.string.market_owner + } + + fun getNpcName(context: Context): String = context.getString(npcNameResource) + + companion object { + const val MARKET = "market" + const val QUEST_SHOP = "questShop" + const val TIME_TRAVELERS_SHOP = "timeTravelersShop" + const val SEASONAL_SHOP = "seasonalShop" + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.java deleted file mode 100644 index 441b2bead..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.habitrpg.android.habitica.models.shops; - -import java.util.List; - -public class ShopCategory { - - public String identifier; - public String text; - public String notes; - public Boolean purchaseAll; - - public List items; - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getNotes() { - return notes; - } - - public void setNotes(String notes) { - this.notes = notes; - } - - public Boolean getPurchaseAll() { - return purchaseAll; - } - - public void setPurchaseAll(Boolean purchaseAll) { - this.purchaseAll = purchaseAll; - } - - public List getItems() { - return items; - } - - public void setItems(List items) { - this.items = items; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.kt new file mode 100644 index 000000000..e7fbb0318 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopCategory.kt @@ -0,0 +1,11 @@ +package com.habitrpg.android.habitica.models.shops + +class ShopCategory { + + var identifier: String = "" + var text: String = "" + var notes: String = "" + var purchaseAll: Boolean? = null + + var items: MutableList = ArrayList() +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.java deleted file mode 100644 index 105cb919a..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.habitrpg.android.habitica.models.shops; - -import android.content.res.Resources; - -import com.google.gson.annotations.SerializedName; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.Task; -import com.habitrpg.android.habitica.models.user.User; - -import io.realm.RealmObject; -import io.realm.annotations.PrimaryKey; - -public class ShopItem extends RealmObject { - - public static final String GEM_FOR_GOLD = "gem"; - @PrimaryKey - public String key; - public String text; - public String notes; - @SerializedName("class") - public String imageName; - public Integer value; - public boolean locked; - public boolean limited; - public String currency; - public String purchaseType; - public String categoryIdentifier; - public Integer limitedNumberLeft; - public ShopItemUnlockCondition unlockCondition; - public String path; - public String isSuggested; - public String pinType; - - public static ShopItem makeGemItem(Resources res) { - ShopItem item = new ShopItem(); - item.key = GEM_FOR_GOLD; - item.text = res.getString(R.string.gem_shop); - item.notes = res.getString(R.string.gem_for_gold_description); - item.imageName = "gem_shop"; - item.value = 20; - item.currency = "gold"; - item.purchaseType = "gems"; - return item; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getNotes() { - return notes; - } - - public void setNotes(String notes) { - this.notes = notes; - } - - public String getImageName() { - if (imageName != null) { - if (imageName.contains(" ")) { - return imageName.split(" ")[1]; - } else { - return imageName; - } - } else { - return "shop_" + key; - } - } - - public void setImageName(String imageName) { - this.imageName = imageName; - } - - public Integer getValue() { - return value; - } - - public void setValue(Integer value) { - this.value = value; - } - - public Boolean getLocked() { - return locked; - } - - public void setLocked(Boolean locked) { - this.locked = locked; - } - - public String getCurrency() { - if (currency == null) { - return ""; - } - return currency; - } - - public void setCurrency(String currency) { - this.currency = currency; - } - - public String getPurchaseType() { - return purchaseType; - } - - public void setPurchaseType(String purchaseType) { - this.purchaseType = purchaseType; - } - - public String getCategoryIdentifier() { - return categoryIdentifier; - } - - public void setCategoryIdentifier(String categoryIdentifier) { - this.categoryIdentifier = categoryIdentifier; - } - - public Integer getLimitedNumberLeft() { - return limitedNumberLeft; - } - - public void setLimitedNumberLeft(Integer limitedNumberLeft) { - this.limitedNumberLeft = limitedNumberLeft; - } - - public ShopItemUnlockCondition getUnlockCondition() { - return unlockCondition; - } - - public void setUnlockCondition(ShopItemUnlockCondition unlockCondition) { - this.unlockCondition = unlockCondition; - } - - public boolean canBuy(User user) { - if (user == null || user.getStats() == null) { - return false; - } - if (getCurrency().equals("gold")) { - return getValue() <= user.getStats().getGp(); - } else if (getCurrency().equals("gems")) { - return getValue() <= (user.getBalance() * 4); - } else { - return false; - } - } - - public boolean isLimited() { - return limited; - } - - public boolean isTypeItem() { - return "eggs".equals(purchaseType) || "hatchingPotions".equals(purchaseType) || "food".equals(purchaseType) || "armoire".equals(purchaseType) || "potion".equals(purchaseType); - } - - public boolean isTypeQuest() { - return "quests".equals(purchaseType); - } - - public boolean isTypeGear() { - return "gear".equals(purchaseType); - } - - public boolean isTypeAnimal() { - return "pets".equals(purchaseType) || "mounts".equals(purchaseType); - } - - @Override - public boolean equals(Object obj) { - if (ShopItem.class.isAssignableFrom(obj.getClass())) { - ShopItem otherItem = (ShopItem) obj; - return this.key.equals(otherItem.key); - } - return super.equals(obj); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt new file mode 100644 index 000000000..27952ad70 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt @@ -0,0 +1,90 @@ +package com.habitrpg.android.habitica.models.shops + +import android.content.res.Resources + +import com.google.gson.annotations.SerializedName +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.models.user.User + +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey + +open class ShopItem : RealmObject() { + @PrimaryKey + var key: String = "" + var text: String = "" + var notes: String = "" + @SerializedName("class") + var imageName: String? = null + get() { + return if (field != null) { + if (field!!.contains(" ")) { + field!!.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1] + } else { + field + } + } else { + "shop_" + key + } + } + + var value: Int = 0 + var locked: Boolean = false + var isLimited: Boolean = false + var currency: String = "" + var purchaseType: String = "" + var categoryIdentifier: String = "" + var limitedNumberLeft: Int? = null + var unlockCondition: ShopItemUnlockCondition? = null + var path: String? = null + var isSuggested: String? = null + var pinType: String? = null + + val isTypeItem: Boolean + get() = "eggs" == purchaseType || "hatchingPotions" == purchaseType || "food" == purchaseType || "armoire" == purchaseType || "potion" == purchaseType + + val isTypeQuest: Boolean + get() = "quests" == purchaseType + + val isTypeGear: Boolean + get() = "gear" == purchaseType + + val isTypeAnimal: Boolean + get() = "pets" == purchaseType || "mounts" == purchaseType + + fun canBuy(user: User?): Boolean { + if (user == null || user.stats == null) { + return false + } + return when(currency) { + "gold" -> value <= user.stats.getGp() + "gems" -> value <= user.balance * 4 + else -> false + } + } + + override fun equals(other: Any?): Boolean { + if (ShopItem::class.java.isAssignableFrom(other!!.javaClass)) { + val otherItem = other as ShopItem? + return this.key == otherItem!!.key + } + return super.equals(other) + } + + companion object { + + const val GEM_FOR_GOLD = "gem" + + fun makeGemItem(res: Resources?): ShopItem { + val item = ShopItem() + item.key = GEM_FOR_GOLD + item.text = res?.getString(R.string.gem_shop) ?: "" + item.notes = res?.getString(R.string.gem_for_gold_description) ?: "" + item.imageName = "gem_shop" + item.value = 20 + item.currency = "gold" + item.purchaseType = "gems" + return item + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.java deleted file mode 100644 index 362ddd186..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.habitrpg.android.habitica.models.shops; - -import com.habitrpg.android.habitica.R; - -import io.realm.RealmObject; -import io.realm.annotations.PrimaryKey; - -public class ShopItemUnlockCondition extends RealmObject { - - @PrimaryKey - String condition; - - public int readableUnlockConditionId() { - switch (this.condition) { - case "party invite": - return R.string.party_invite; - default: - return R.string.empty; - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.kt new file mode 100644 index 000000000..4c5513d14 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItemUnlockCondition.kt @@ -0,0 +1,17 @@ +package com.habitrpg.android.habitica.models.shops + +import com.habitrpg.android.habitica.R + +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey + +open class ShopItemUnlockCondition : RealmObject() { + + @PrimaryKey + internal var condition: String? = null + + fun readableUnlockConditionId(): Int = when (this.condition) { + "party invite" -> R.string.party_invite + else -> R.string.empty + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.java index d13e8fe6e..220757e44 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.java @@ -42,7 +42,7 @@ public class GemPurchaseActivity extends BaseActivity implements InAppMessageLis CrashlyticsProxy crashlyticsProxy; @BindView(R.id.tab_layout) TabLayout tabLayout; - @BindView(R.id.view_pager) + @BindView(R.id.viewPager) ViewPager viewPager; List fragments = new ArrayList<>(); private ActivityCheckout checkout; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java index 308d542d2..5f12480ba 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java @@ -31,7 +31,7 @@ public class IntroActivity extends BaseActivity implements View.OnClickListener, @Inject public ApiClient apiClient; - @BindView(R.id.view_pager) + @BindView(R.id.viewPager) ViewPager pager; @BindView(R.id.view_pager_indicator) IconPageIndicator indicator; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/PartyInviteActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/PartyInviteActivity.java index 9cefe0c91..f44d265f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/PartyInviteActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/PartyInviteActivity.java @@ -48,7 +48,7 @@ public class PartyInviteActivity extends BaseActivity { UserRepository userRepository; @BindView(R.id.tab_layout) TabLayout tabLayout; - @BindView(R.id.view_pager) + @BindView(R.id.viewPager) ViewPager viewPager; List fragments = new ArrayList<>(); private String userIdToInvite; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SetupActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SetupActivity.java index b25086f3c..8aaf7e85d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SetupActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/SetupActivity.java @@ -36,7 +36,6 @@ import com.habitrpg.android.habitica.ui.views.FadingViewPager; import com.viewpagerindicator.IconPageIndicator; import com.viewpagerindicator.IconPagerAdapter; -import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.util.Calendar; @@ -61,7 +60,7 @@ public class SetupActivity extends BaseActivity implements ViewPager.OnPageChang protected UserRepository userRepository; @Inject protected TaskRepository taskRepository; - @BindView(R.id.view_pager) + @BindView(R.id.viewPager) FadingViewPager pager; @BindView(R.id.nextButton) Button nextButton; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.java deleted file mode 100644 index a36aa2c12..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.java +++ /dev/null @@ -1,256 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.inventory; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Shader; -import android.graphics.drawable.BitmapDrawable; -import android.net.Uri; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.text.Html; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; - -import com.facebook.common.executors.CallerThreadExecutor; -import com.facebook.common.references.CloseableReference; -import com.facebook.datasource.DataSource; -import com.facebook.drawee.backends.pipeline.Fresco; -import com.facebook.drawee.view.SimpleDraweeView; -import com.facebook.imagepipeline.core.ImagePipeline; -import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber; -import com.facebook.imagepipeline.image.CloseableImage; -import com.facebook.imagepipeline.request.ImageRequest; -import com.facebook.imagepipeline.request.ImageRequestBuilder; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.inventory.Item; -import com.habitrpg.android.habitica.models.shops.Shop; -import com.habitrpg.android.habitica.models.shops.ShopCategory; -import com.habitrpg.android.habitica.models.shops.ShopItem; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder; -import com.habitrpg.android.habitica.ui.viewHolders.ShopItemViewHolder; - -import org.greenrobot.eventbus.EventBus; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.realm.RealmResults; -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; - -public class ShopRecyclerAdapter extends RecyclerView.Adapter { - - private List items; - private String shopIdentifier; - private Map ownedItems = new HashMap<>(); - private String shopSpriteSuffix; - private User user; - private List pinnedItemKeys; - - public void setShop(Shop shop, String shopSpriteSuffix) { - this.shopSpriteSuffix = shopSpriteSuffix; - shopIdentifier = shop.identifier; - items = new ArrayList<>(); - items.add(shop); - for (ShopCategory category : shop.categories) { - if (category.items != null && category.items.size() > 0) { - items.add(category); - for (ShopItem item : category.items) { - item.categoryIdentifier = category.getIdentifier(); - items.add(item); - } - } - } - notifyDataSetChanged(); - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if (viewType == 0) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.shop_header, parent, false); - - return new ShopHeaderViewHolder(view); - } else if (viewType == 1) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.shop_section_header, parent, false); - - return new SectionViewHolder(view); - } else if (viewType == 2) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(getEmptyViewResource(), parent, false); - return new EmptyStateViewHolder(view); - } else { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.row_shopitem, parent, false); - ShopItemViewHolder viewHolder = new ShopItemViewHolder(view); - viewHolder.shopIdentifier = shopIdentifier; - return viewHolder; - } - } - - private int getEmptyViewResource() { - if (Shop.SEASONAL_SHOP.equals(this.shopIdentifier)) { - return R.layout.empty_view_seasonal_shop; - } else if (Shop.TIME_TRAVELERS_SHOP.equals(this.shopIdentifier)) { - return R.layout.empty_view_timetravelers; - } - return R.layout.simple_textview; - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - if (position > (this.items.size()-1)) { - return; - } - Object obj = this.items.get(position); - if (obj.getClass().equals(Shop.class)) { - ((ShopHeaderViewHolder) holder).bind((Shop) obj, shopSpriteSuffix); - } else if (obj.getClass().equals(ShopCategory.class)) { - ((SectionViewHolder) holder).bind(((ShopCategory) obj).getText()); - } else if (obj.getClass().equals(ShopItem.class)) { - ShopItem item = (ShopItem) items.get(position); - ((ShopItemViewHolder) holder).bind(item, item.canBuy(user)); - if (ownedItems.containsKey(item.getKey())) { - ((ShopItemViewHolder) holder).setItemCount(ownedItems.get(item.getKey()).getOwned()); - } - if (pinnedItemKeys != null) { - ((ShopItemViewHolder) holder).setIsPinned(pinnedItemKeys.contains(item.getKey())); - } else { - ((ShopItemViewHolder) holder).setIsPinned(false); - } - } - } - - @Override - public int getItemViewType(int position) { - if (position > (this.items.size()-1)) { - return 2; - } else if (this.items.get(position).getClass().equals(Shop.class)) { - return 0; - } else if (this.items.get(position).getClass().equals(ShopCategory.class)) { - return 1; - } else { - return 3; - } - } - - @Override - public int getItemCount() { - int size = items != null ? items.size() : 0; - if (size == 1) { - return 2; - } - return size; - } - - public void setOwnedItems(Map ownedItems) { - this.ownedItems = ownedItems; - this.notifyDataSetChanged(); - } - - public void setUser(User user) { - this.user = user; - this.notifyDataSetChanged(); - } - - public void setPinnedItemKeys(List pinnedItemKeys) { - this.pinnedItemKeys = pinnedItemKeys; - this.notifyDataSetChanged(); - } - - static class ShopHeaderViewHolder extends RecyclerView.ViewHolder { - - private final Context context; - @BindView(R.id.sceneView) - public SimpleDraweeView sceneView; - @BindView(R.id.backgroundView) - public ImageView backgroundView; - - @BindView(R.id.name_plate) - public TextView namePlate; - - @BindView(R.id.descriptionView) - public TextView descriptionView; - - - ShopHeaderViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - context = itemView.getContext(); - descriptionView.setMovementMethod(LinkMovementMethod.getInstance()); - } - - public void bind(Shop shop, String shopSpriteSuffix) { - DataBindingUtils.loadImage(sceneView, shop.identifier+"_scene"+shopSpriteSuffix); - - backgroundView.setScaleType(ImageView.ScaleType.FIT_START); - - ImageRequest imageRequest = ImageRequestBuilder - .newBuilderWithSource(Uri.parse("https://habitica-assets.s3.amazonaws.com/mobileApp/images/" + shop.identifier+"_background"+shopSpriteSuffix+".png")) - .build(); - - ImagePipeline imagePipeline = Fresco.getImagePipeline(); - final DataSource> - dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); - - dataSource.subscribe(new BaseBitmapDataSubscriber() { - - @Override - public void onNewResultImpl(@Nullable Bitmap bitmap) { - if (dataSource.isFinished() && bitmap != null){ - float aspectRatio = bitmap.getWidth() / - (float) bitmap.getHeight(); - int height = (int) context.getResources().getDimension(R.dimen.shop_height); - int width = Math.round(height * aspectRatio); - BitmapDrawable drawable = new BitmapDrawable(context.getResources(), Bitmap.createScaledBitmap(bitmap, width, height, false)); - drawable.setTileModeX(Shader.TileMode.REPEAT); - Observable.just(drawable) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(bitmapDrawable -> backgroundView.setBackground(bitmapDrawable), RxErrorHandler.handleEmptyError()); - dataSource.close(); - } - } - - @Override - public void onFailureImpl(DataSource dataSource) { - if (dataSource != null) { - dataSource.close(); - } - } - }, CallerThreadExecutor.getInstance()); - - descriptionView.setText(Html.fromHtml(shop.getNotes())); - namePlate.setText(shop.getNpcNameResource()); - } - - } - - public static class EmptyStateViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.subscribeButton) - @Nullable - Button subscribeButton; - - public EmptyStateViewHolder(View view) { - super(view); - ButterKnife.bind(this, view); - - if (subscribeButton != null) { - subscribeButton.setOnClickListener(view1 -> EventBus.getDefault().post(new OpenGemPurchaseFragmentCommand())); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt new file mode 100644 index 000000000..d042d8420 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt @@ -0,0 +1,286 @@ +package com.habitrpg.android.habitica.ui.adapter.inventory + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Shader +import android.graphics.drawable.BitmapDrawable +import android.net.Uri +import android.support.v7.widget.RecyclerView +import android.text.Html +import android.text.method.LinkMovementMethod +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.Button +import android.widget.ImageView +import android.widget.TextView +import butterknife.ButterKnife +import com.facebook.common.executors.CallerThreadExecutor +import com.facebook.common.references.CloseableReference +import com.facebook.datasource.DataSource +import com.facebook.drawee.backends.pipeline.Fresco +import com.facebook.drawee.view.SimpleDraweeView +import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber +import com.facebook.imagepipeline.image.CloseableImage +import com.facebook.imagepipeline.request.ImageRequestBuilder +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand +import com.habitrpg.android.habitica.extensions.bindView +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.inventory.Item +import com.habitrpg.android.habitica.models.shops.Shop +import com.habitrpg.android.habitica.models.shops.ShopCategory +import com.habitrpg.android.habitica.models.shops.ShopItem +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder +import com.habitrpg.android.habitica.ui.viewHolders.ShopItemViewHolder +import org.greenrobot.eventbus.EventBus +import rx.Observable +import rx.android.schedulers.AndroidSchedulers +import rx.functions.Action1 + + +class ShopRecyclerAdapter : RecyclerView.Adapter() { + + private val items: MutableList = ArrayList() + private var shopIdentifier: String? = null + private var ownedItems: Map = HashMap() + private var shopSpriteSuffix: String? = null + var context: Context? = null + var user: User? = null + set(value) { + field = value + this.notifyDataSetChanged() + } + private var pinnedItemKeys: List = ArrayList() + + var gearCategories: MutableList = ArrayList() + set(value) { + field = value + notifyDataSetChanged() + } + + internal var selectedGearCategory: String = "" + set(value) { + field = value + if (field != "") { + notifyDataSetChanged() + } + } + + private val emptyViewResource: Int + get() = when (this.shopIdentifier) { + Shop.SEASONAL_SHOP -> R.layout.empty_view_seasonal_shop + Shop.TIME_TRAVELERS_SHOP -> R.layout.empty_view_timetravelers + else -> R.layout.simple_textview + } + + fun setShop(shop: Shop?, shopSpriteSuffix: String) { + if (shop == null) { + return + } + this.shopSpriteSuffix = shopSpriteSuffix + shopIdentifier = shop.identifier + items.clear() + items.add(shop) + for (category in shop.categories) { + if (category.items.size > 0) { + items.add(category) + for (item in category.items) { + item.categoryIdentifier = category.identifier + items.add(item) + } + } + } + notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = + when (viewType) { + 0 -> { + val view = parent.inflate(R.layout.shop_header) + ShopHeaderViewHolder(view) + } + 1 -> { + val view = parent.inflate(R.layout.shop_section_header) + SectionViewHolder(view) + } + 2 -> { + val view = parent.inflate(emptyViewResource) + EmptyStateViewHolder(view) + } + else -> { + val view = parent.inflate(R.layout.row_shopitem) + val viewHolder = ShopItemViewHolder(view) + viewHolder.shopIdentifier = shopIdentifier + viewHolder + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val obj = getItem(position) + if (obj != null) { + when (obj.javaClass) { + Shop::class.java -> (holder as ShopHeaderViewHolder).bind(obj as Shop, shopSpriteSuffix) + ShopCategory::class.java -> { + val category = obj as ShopCategory + (holder as SectionViewHolder).bind((category).text) + if (gearCategories.contains(category)) { + val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, gearCategories.map { it.identifier }) + holder.spinnerAdapter = adapter + holder.selectedItem = gearCategories.indexOf(category) + holder.spinnerSelectionChanged = { + if (selectedGearCategory != gearCategories[holder.selectedItem].identifier) { + selectedGearCategory = gearCategories[holder.selectedItem].identifier + } + } + } + } + ShopItem::class.java -> { + val item = obj as ShopItem + (holder as ShopItemViewHolder).bind(item, item.canBuy(user)) + if (ownedItems.containsKey(item.key)) { + holder.setItemCount(ownedItems[item.key]?.owned ?: 0) + } + holder.setIsPinned(pinnedItemKeys.contains(item.key)) + } + String::class.java -> (holder as EmptyStateViewHolder).text = obj as String + } + } + } + + private fun getItem(position: Int): Any? { + if (items.size == 0) { + return null + } + if (position == 0) { + return items[0] + } + if (position <= getGearItemCount()) { + return when { + position == 1 -> getSelectedShopCategory() + getSelectedShopCategory()?.items?.size ?: 0 <= position-2 -> return context?.getString(R.string.equipment_empty) + else -> getSelectedShopCategory()?.items?.get(position-2) + } + } else { + val itemPosition = position - getGearItemCount() + if (itemPosition > items.size-1) { + return null + } + return items[itemPosition] + } + } + + override fun getItemViewType(position: Int): Int = when(getItem(position)?.javaClass) { + Shop::class.java -> 0 + ShopCategory::class.java -> 1 + ShopItem::class.java -> 3 + else -> 2 + } + + override fun getItemCount(): Int { + val size = items.size + getGearItemCount() + return if (size == 1) { + 2 + } else size + } + + private fun getGearItemCount(): Int { + return if (selectedGearCategory == "") { + 0 + } else { + val selectedCategory: ShopCategory? = getSelectedShopCategory() + return if (selectedCategory != null) { + return if (selectedCategory.items.size == 0) { + 2 + } else { + selectedCategory.items.size+1 + } + } else { + 0 + } + } + } + + private fun getSelectedShopCategory() = + gearCategories.firstOrNull { selectedGearCategory == it.identifier } + + fun setOwnedItems(ownedItems: Map) { + this.ownedItems = ownedItems + this.notifyDataSetChanged() + } + + fun setPinnedItemKeys(pinnedItemKeys: List) { + this.pinnedItemKeys = pinnedItemKeys + this.notifyDataSetChanged() + } + + internal class ShopHeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + private val context: Context + private val descriptionView: TextView by bindView(itemView, R.id.descriptionView) + private val sceneView: SimpleDraweeView by bindView(itemView, R.id.sceneView) + private val backgroundView: ImageView by bindView(itemView, R.id.backgroundView) + private val namePlate: TextView by bindView(itemView, R.id.namePlate) + + init { + ButterKnife.bind(this, itemView) + context = itemView.context + descriptionView.movementMethod = LinkMovementMethod.getInstance() + } + + fun bind(shop: Shop, shopSpriteSuffix: String?) { + DataBindingUtils.loadImage(sceneView, shop.identifier + "_scene" + shopSpriteSuffix) + + backgroundView.scaleType = ImageView.ScaleType.FIT_START + + val imageRequest = ImageRequestBuilder + .newBuilderWithSource(Uri.parse("https://habitica-assets.s3.amazonaws.com/mobileApp/images/" + shop.identifier + "_background" + shopSpriteSuffix + ".png")) + .build() + + val imagePipeline = Fresco.getImagePipeline() + val dataSource = imagePipeline.fetchDecodedImage(imageRequest, this) + + dataSource.subscribe(object : BaseBitmapDataSubscriber() { + override fun onFailureImpl(dataSource: DataSource>?) { + dataSource?.close() + } + + public override fun onNewResultImpl(bitmap: Bitmap?) { + if (dataSource.isFinished && bitmap != null) { + val aspectRatio = bitmap.width / bitmap.height.toFloat() + val height = context.resources.getDimension(R.dimen.shop_height).toInt() + val width = Math.round(height * aspectRatio) + val drawable = BitmapDrawable(context.resources, Bitmap.createScaledBitmap(bitmap, width, height, false)) + drawable.tileModeX = Shader.TileMode.REPEAT + Observable.just(drawable) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(Action1 { backgroundView.background = it }, RxErrorHandler.handleEmptyError()) + dataSource.close() + } + } + }, CallerThreadExecutor.getInstance()) + + descriptionView.text = Html.fromHtml(shop.notes) + namePlate.setText(shop.npcNameResource) + } + + } + + class EmptyStateViewHolder(view: View) : RecyclerView.ViewHolder(view) { + private val subscribeButton: Button? by bindView(itemView, R.id.subscribeButton) + private val textView: TextView? by bindView(itemView, R.id.textView) + init { + ButterKnife.bind(this, view) + subscribeButton?.setOnClickListener { EventBus.getDefault().post(OpenGemPurchaseFragmentCommand()) } + } + + var text: String? = null + set(value) { + field = value + textView?.text = field + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.java index 7d6046d4e..66cdf8105 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.java @@ -47,7 +47,7 @@ public class ItemRecyclerFragment extends BaseFragment { private static final String ITEM_TYPE_KEY = "CLASS_TYPE_KEY"; @BindView(R.id.recyclerView) public RecyclerViewEmptySupport recyclerView; - @BindView(R.id.empty_view) + @BindView(R.id.emptyView) public View emptyView; @BindView(R.id.empty_text_view) public TextView emptyTextView; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.java index 7e7711ea5..590c9fabc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.java @@ -27,7 +27,7 @@ public class ItemsFragment extends BaseMainFragment { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); viewPager.setCurrentItem(0); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.java deleted file mode 100644 index 10f5a8a4e..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.habitrpg.android.habitica.ui.fragments.inventory.shops; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.GridLayoutManager; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.data.InventoryRepository; -import com.habitrpg.android.habitica.data.UserRepository; -import com.habitrpg.android.habitica.helpers.RemoteConfigManager; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.shops.Shop; -import com.habitrpg.android.habitica.models.shops.ShopCategory; -import com.habitrpg.android.habitica.models.shops.ShopItem; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter; -import com.habitrpg.android.habitica.ui.fragments.BaseFragment; -import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport; -import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class ShopFragment extends BaseFragment { - private static final String SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY"; - - @BindView(R.id.recyclerView) - public RecyclerViewEmptySupport recyclerView; - @BindView(R.id.empty_view) - public TextView emptyView; - public ShopRecyclerAdapter adapter; - public String shopIdentifier; - public User user; - public Shop shop; - @Inject - InventoryRepository inventoryRepository; - @Inject - UserRepository userRepository; - @Inject - RemoteConfigManager configManager; - - private View view; - - private GridLayoutManager layoutManager; - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - if (view == null) { - view = inflater.inflate(R.layout.fragment_recyclerview, container, false); - } - - unbinder = ButterKnife.bind(this, view); - - recyclerView.setBackgroundResource(R.color.white); - - adapter = (ShopRecyclerAdapter) recyclerView.getAdapter(); - if (adapter == null) { - adapter = new ShopRecyclerAdapter(); - recyclerView.setAdapter(adapter); - recyclerView.setItemAnimator(new SafeDefaultItemAnimator()); - } - if (layoutManager == null) { - layoutManager = new GridLayoutManager(getContext(), 2); - layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - if (adapter.getItemViewType(position) < 3) { - return layoutManager.getSpanCount(); - } else { - return 1; - } - } - }); - recyclerView.setLayoutManager(layoutManager); - } - - if (savedInstanceState != null) { - this.shopIdentifier = savedInstanceState.getString(SHOP_IDENTIFIER_KEY, ""); - } - - if (shop == null) { - loadShopInventory(); - } else { - adapter.setShop(shop, configManager.shopSpriteSuffix()); - } - adapter.setUser(user); - - return view; - } - - @Override - public void onDestroyView() { - userRepository.close(); - inventoryRepository.close(); - super.onDestroyView(); - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - final View finalView = view; - finalView.post(() -> setGridSpanCount(finalView.getWidth())); - } - - private void loadShopInventory() { - String shopUrl = ""; - switch (this.shopIdentifier) { - case Shop.MARKET: - shopUrl = "market"; - break; - case Shop.QUEST_SHOP: - shopUrl = "quests"; - break; - case Shop.TIME_TRAVELERS_SHOP: - shopUrl = "time-travelers"; - break; - case Shop.SEASONAL_SHOP: - shopUrl = "seasonal"; - break; - } - this.inventoryRepository.fetchShopInventory(shopUrl) - .map(shop1 -> { - if (shop1.identifier.equals(Shop.MARKET)) { - if (user != null && user.isValid() && user.getPurchased().getPlan().isActive()) { - ShopCategory specialCategory = new ShopCategory(); - specialCategory.text = getString(R.string.special); - specialCategory.items = new ArrayList<>(); - ShopItem item = ShopItem.makeGemItem(getContext().getResources()); - item.limitedNumberLeft = user.getPurchased().getPlan().numberOfGemsLeft(); - specialCategory.items.add(item); - shop1.categories.add(specialCategory); - } - } - return shop1; - }) - .subscribe(shop -> { - this.shop = shop; - this.adapter.setShop(shop, configManager.shopSpriteSuffix()); - }, RxErrorHandler.handleEmptyError()); - - compositeSubscription.add(this.inventoryRepository.getOwnedItems(user) - .subscribe(ownedItems -> adapter.setOwnedItems(ownedItems), RxErrorHandler.handleEmptyError())); - compositeSubscription.add(this.inventoryRepository.getInAppRewards() - .map(shopItems -> { - List itemKeys = new ArrayList<>(); - for (ShopItem item : shopItems) { - itemKeys.add(item.getKey()); - } - return itemKeys; - }) - .subscribe(pinnedItems -> adapter.setPinnedItemKeys(pinnedItems), RxErrorHandler.handleEmptyError())); - } - - @Override - public void injectFragment(AppComponent component) { - component.inject(this); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SHOP_IDENTIFIER_KEY, this.shopIdentifier); - } - - private void setGridSpanCount(int width) { - int spanCount = 0; - if (getContext() != null && getContext().getResources() != null) { - float itemWidth; - itemWidth = getContext().getResources().getDimension(R.dimen.pet_width); - - spanCount = (int) (width / itemWidth); - } - if (spanCount == 0) { - spanCount = 1; - } - layoutManager.setSpanCount(spanCount); - layoutManager.requestLayout(); - } - -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt new file mode 100644 index 000000000..f25239b9f --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt @@ -0,0 +1,179 @@ +package com.habitrpg.android.habitica.ui.fragments.inventory.shops + +import android.os.Bundle +import android.support.v7.widget.GridLayoutManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.components.AppComponent +import com.habitrpg.android.habitica.data.InventoryRepository +import com.habitrpg.android.habitica.data.UserRepository +import com.habitrpg.android.habitica.helpers.RemoteConfigManager +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.shops.Shop +import com.habitrpg.android.habitica.models.shops.ShopCategory +import com.habitrpg.android.habitica.models.shops.ShopItem +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter +import com.habitrpg.android.habitica.ui.fragments.BaseFragment +import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import kotlinx.android.synthetic.main.fragment_recyclerview.* +import rx.functions.Action1 +import javax.inject.Inject + +class ShopFragment : BaseFragment() { + + var adapter: ShopRecyclerAdapter? = null + var shopIdentifier: String? = null + var user: User? = null + var shop: Shop? = null + @Inject + lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var userRepository: UserRepository + @Inject + lateinit var configManager: RemoteConfigManager + + private val layoutManager: GridLayoutManager by lazy { + val layoutManager = GridLayoutManager(context, 2) + layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + return if (adapter?.getItemViewType(position) ?: 0 < 3) { + layoutManager.spanCount + } else { + 1 + } + } + } + return@lazy layoutManager + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + super.onCreateView(inflater, container, savedInstanceState) + return inflater.inflate(R.layout.fragment_recyclerview, container, false) + } + + override fun onDestroyView() { + userRepository.close() + inventoryRepository.close() + super.onDestroyView() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + recyclerView.setBackgroundResource(R.color.white) + + adapter = recyclerView.adapter as ShopRecyclerAdapter? + if (adapter == null) { + adapter = ShopRecyclerAdapter() + adapter?.context = context + recyclerView.adapter = adapter + recyclerView.itemAnimator = SafeDefaultItemAnimator() + } + + if (recyclerView.layoutManager == null) { + recyclerView.layoutManager = layoutManager + } + + if (savedInstanceState != null) { + this.shopIdentifier = savedInstanceState.getString(SHOP_IDENTIFIER_KEY, "") + } + + if (shop == null) { + loadShopInventory() + } else { + adapter?.setShop(shop, configManager.shopSpriteSuffix()) + } + adapter?.user = user + + view.post { setGridSpanCount(view.width) } + } + + private fun loadShopInventory() { + val shopUrl = when (this.shopIdentifier) { + Shop.MARKET -> "market" + Shop.QUEST_SHOP -> "quests" + Shop.TIME_TRAVELERS_SHOP -> "time-travelers" + Shop.SEASONAL_SHOP -> "seasonal" + else -> "" + } + this.inventoryRepository.retrieveShopInventory(shopUrl) + .map { shop1 -> + if (shop1.identifier == Shop.MARKET) { + val user = user + if (user != null && user.isValid && user.purchased.plan.isActive) { + val specialCategory = ShopCategory() + specialCategory.text = getString(R.string.special) + val item = ShopItem.makeGemItem(context?.resources) + item.limitedNumberLeft = user.purchased.plan.numberOfGemsLeft() + specialCategory.items.add(item) + shop1.categories.add(specialCategory) + } + } + shop1 + } + .subscribe(Action1 { + this.shop = it + if (Shop.MARKET == shopIdentifier) { + loadMarketGear() + } + this.adapter?.setShop(it, configManager.shopSpriteSuffix()) + }, RxErrorHandler.handleEmptyError()) + + + + compositeSubscription.add(this.inventoryRepository.getOwnedItems(user) + .subscribe(Action1 { adapter?.setOwnedItems(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(this.inventoryRepository.inAppRewards + .map> { it.map { it.key } } + .subscribe(Action1 { adapter?.setPinnedItemKeys(it) }, RxErrorHandler.handleEmptyError())) + } + + private fun loadMarketGear() { + inventoryRepository.retrieveMarketGear() + .zipWith(inventoryRepository.ownedEquipment.first().map { it.map { it.key } }, { shop, equipment -> + for (category in shop.categories) { + val items = category.items.filter({ + !equipment.contains(it.key) + }) + category.items.clear() + category.items.addAll(items) + } + shop + }) + .subscribe(Action1 { + adapter?.selectedGearCategory = user?.stats?.habitClass ?: "" + adapter?.gearCategories = it.categories + }, RxErrorHandler.handleEmptyError()) + } + + override fun injectFragment(component: AppComponent) { + component.inject(this) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putString(SHOP_IDENTIFIER_KEY, this.shopIdentifier) + } + + private fun setGridSpanCount(width: Int) { + var spanCount = 0 + val context = context + if (context != null && context.resources != null) { + val itemWidth: Float = context.resources.getDimension(R.dimen.pet_width) + + spanCount = (width / itemWidth).toInt() + } + if (spanCount == 0) { + spanCount = 1 + } + layoutManager.spanCount = spanCount + layoutManager.requestLayout() + } + + companion object { + private const val SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY" + } + +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.java deleted file mode 100644 index 421254d08..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.habitrpg.android.habitica.ui.fragments.inventory.shops; - -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.data.InventoryRepository; -import com.habitrpg.android.habitica.models.shops.Shop; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment; -import com.habitrpg.android.habitica.ui.views.CurrencyViews; - -import javax.inject.Inject; - -public class ShopsFragment extends BaseMainFragment { - - @Inject - InventoryRepository inventoryRepository; - - public ViewPager viewPager; - private CurrencyViews currencyView; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - this.usesTabLayout = true; - hideToolbar(); - disableToolbarScrolling(); - super.onCreateView(inflater, container, savedInstanceState); - View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - - viewPager = (ViewPager) v.findViewById(R.id.view_pager); - - viewPager.setCurrentItem(0); - - setViewPagerAdapter(); - - return v; - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - currencyView = new CurrencyViews(getContext()); - if (toolbarAccessoryContainer != null) { - toolbarAccessoryContainer.addView(currencyView); - } - updateCurrencyView(); - } - - @Override - public void onDestroyView() { - if (toolbarAccessoryContainer != null) { - toolbarAccessoryContainer.removeView(currencyView); - } - showToolbar(); - enableToolbarScrolling(); - inventoryRepository.close(); - super.onDestroyView(); - } - - @Override - public void injectFragment(AppComponent component) { - component.inject(this); - } - - public void setViewPagerAdapter() { - android.support.v4.app.FragmentManager fragmentManager = getChildFragmentManager(); - - viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { - - @Override - public Fragment getItem(int position) { - - ShopFragment fragment = new ShopFragment(); - - switch (position) { - case 0: { - fragment.shopIdentifier = Shop.MARKET; - break; - } - case 1: { - fragment.shopIdentifier = Shop.QUEST_SHOP; - break; - } - case 2: { - fragment.shopIdentifier = Shop.SEASONAL_SHOP; - break; - } - case 3: { - fragment.shopIdentifier = Shop.TIME_TRAVELERS_SHOP; - break; - } - } - fragment.user = ShopsFragment.this.user; - - return fragment; - } - - @Override - public int getCount() { - return 4; - } - - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case 0: - return getContext().getString(R.string.market); - case 1: - return getContext().getString(R.string.quests); - case 2: - return getContext().getString(R.string.seasonalShop); - case 3: - return getContext().getString(R.string.timeTravelers); - } - return ""; - } - }); - - if (tabLayout != null && viewPager != null) { - tabLayout.setupWithViewPager(viewPager); - } - } - - - @Override - public String customTitle() { - if (!isAdded()) { - return ""; - } - return getString(R.string.sidebar_shops); - } - - @Override - public void updateUserData(User user) { - super.updateUserData(user); - updateCurrencyView(); - } - - private void updateCurrencyView() { - if (user == null || currencyView == null) { - return; - } - currencyView.setGold(user.getStats().getGp()); - currencyView.setGems(user.getGemCount()); - currencyView.setHourglasses(user.getHourglassCount()); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt new file mode 100644 index 000000000..9e71113e2 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopsFragment.kt @@ -0,0 +1,115 @@ +package com.habitrpg.android.habitica.ui.fragments.inventory.shops + +import android.os.Bundle +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentPagerAdapter +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.components.AppComponent +import com.habitrpg.android.habitica.data.InventoryRepository +import com.habitrpg.android.habitica.models.shops.Shop +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment +import com.habitrpg.android.habitica.ui.views.CurrencyViews +import kotlinx.android.synthetic.main.fragment_viewpager.* +import javax.inject.Inject + +class ShopsFragment : BaseMainFragment() { + + @Inject + lateinit var inventoryRepository: InventoryRepository + + private val currencyView: CurrencyViews by lazy { + CurrencyViews(context) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + this.usesTabLayout = true + hideToolbar() + disableToolbarScrolling() + super.onCreateView(inflater, container, savedInstanceState) + return inflater.inflate(R.layout.fragment_viewpager, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewPager.currentItem = 0 + setViewPagerAdapter() + toolbarAccessoryContainer?.addView(currencyView) + updateCurrencyView() + } + + override fun onDestroyView() { + toolbarAccessoryContainer?.removeView(currencyView) + showToolbar() + enableToolbarScrolling() + inventoryRepository.close() + super.onDestroyView() + } + + override fun injectFragment(component: AppComponent) { + component.inject(this) + } + + private fun setViewPagerAdapter() { + val fragmentManager = childFragmentManager + + viewPager!!.adapter = object : FragmentPagerAdapter(fragmentManager) { + + override fun getItem(position: Int): Fragment { + + val fragment = ShopFragment() + + fragment.shopIdentifier = when (position) { + 0 -> Shop.MARKET + 1 -> Shop.QUEST_SHOP + 2 -> Shop.SEASONAL_SHOP + 3 -> Shop.TIME_TRAVELERS_SHOP + else -> "" + } + fragment.user = this@ShopsFragment.user + + return fragment + } + + override fun getCount(): Int = 4 + + override fun getPageTitle(position: Int): CharSequence? { + return when (position) { + 0 -> return context?.getString(R.string.market) + 1 -> return context?.getString(R.string.quests) + 2 -> return context?.getString(R.string.seasonalShop) + 3 -> return context?.getString(R.string.timeTravelers) + else -> "" + } + } + } + + if (tabLayout != null && viewPager != null) { + tabLayout!!.setupWithViewPager(viewPager) + } + } + + + override fun customTitle(): String { + return if (!isAdded) { + "" + } else getString(R.string.sidebar_shops) + } + + override fun updateUserData(user: User) { + super.updateUserData(user) + updateCurrencyView() + } + + private fun updateCurrencyView() { + if (user == null) { + return + } + currencyView.setGold(user!!.stats.getGp()) + currencyView.setGems(user!!.gemCount) + currencyView.setHourglasses(user!!.hourglassCount) + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.java index c2fce9256..a7df8dcec 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.java @@ -23,7 +23,7 @@ public class StableFragment extends BaseMainFragment { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); viewPager.setCurrentItem(0); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.java index 1cbf425dc..0e5553f39 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.java @@ -40,7 +40,7 @@ public class StableRecyclerFragment extends BaseFragment { @BindView(R.id.recyclerView) public RecyclerViewEmptySupport recyclerView; - @BindView(R.id.empty_view) + @BindView(R.id.emptyView) public TextView emptyView; public StableRecyclerAdapter adapter; public String itemType; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java index 0945dc9ed..af03fc95c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java @@ -6,7 +6,6 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -51,7 +50,7 @@ public class GuildFragment extends BaseMainFragment implements Action1 { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); viewPager.setCurrentItem(0); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java index 9f4b7f6db..9a1464972 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java @@ -41,7 +41,7 @@ public class TavernFragment extends BaseMainFragment { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); viewPager.setCurrentItem(0); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java index ccd991d05..d826411c7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java @@ -46,7 +46,7 @@ public class ChallengeListFragment extends BaseMainFragment implements SwipeRefr SwipeRefreshLayout swipeRefreshLayout; @BindView(R.id.recyclerView) RecyclerViewEmptySupport recyclerView; - @BindView(R.id.empty_view) + @BindView(R.id.emptyView) public View emptyView; private ChallengesListViewAdapter challengeAdapter; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java index 989293b78..2f310ea78 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java @@ -39,7 +39,7 @@ public class ChallengesOverviewFragment extends BaseMainFragment { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); setViewPagerAdapter(); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java index 950996188..b2eff9de2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java @@ -63,7 +63,7 @@ public class PartyFragment extends BaseMainFragment { super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = (ViewPager) v.findViewById(R.id.view_pager); + viewPager = (ViewPager) v.findViewById(R.id.viewPager); viewPager.setCurrentItem(0); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.java index 87fa1af2d..4bb906f38 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.java @@ -7,10 +7,8 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.FragmentActivity; import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.SimpleItemAnimator; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.TypedValue; import android.view.LayoutInflater; @@ -83,7 +81,7 @@ public class TaskRecyclerViewFragment extends BaseFragment implements View.OnCli @BindView(R.id.recyclerView) public RecyclerViewEmptySupport recyclerView; - @BindView(R.id.empty_view) + @BindView(R.id.emptyView) ViewGroup emptyView; @BindView(R.id.empty_view_title) TextView emptyViewTitle; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.java index 625ddc0d9..4661b1c9e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.java @@ -77,7 +77,7 @@ public class TasksFragment extends BaseMainFragment { View v = inflater.inflate(R.layout.fragment_viewpager, container, false); - viewPager = v.findViewById(R.id.view_pager); + viewPager = v.findViewById(R.id.viewPager); View view = inflater.inflate(R.layout.floating_menu_tasks, floatingMenuWrapper, true); if (FloatingActionMenu.class.equals(view.getClass())) { floatingMenu = (FloatingActionMenu) view; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.java deleted file mode 100644 index 5d09ab54b..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.habitrpg.android.habitica.ui.viewHolders; - -import android.content.Context; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.widget.Button; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class SectionViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.label) - TextView label; - - @BindView(R.id.purchaseSetButton) - @Nullable - Button purchaseSetButton; - - Context context; - - public SectionViewHolder(View itemView) { - super(itemView); - context = itemView.getContext(); - ButterKnife.bind(this, itemView); - if (this.purchaseSetButton != null) { - this.purchaseSetButton.setVisibility(View.GONE); - - } - } - - public void bind(String title) { - try { - Integer stringID = context.getResources().getIdentifier("section" + title, "string", context.getPackageName()); - this.label.setText(context.getString(stringID)); - } catch (Exception e) { - this.label.setText(title); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt new file mode 100644 index 000000000..7fb7ad314 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/SectionViewHolder.kt @@ -0,0 +1,60 @@ +package com.habitrpg.android.habitica.ui.viewHolders + +import android.content.Context +import android.support.v7.widget.RecyclerView +import android.view.View +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.Button +import android.widget.Spinner +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.bindView + +class SectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + private val label: TextView by bindView(itemView, R.id.label) + private val purchaseSetButton: Button? by bindView(itemView, R.id.purchaseSetButton) + private val selectionSpinner: Spinner? by bindView(itemView, R.id.classSelectionSpinner) + + var context: Context = itemView.context + + var spinnerSelectionChanged: (() -> Unit)? = null + + init { + this.purchaseSetButton?.visibility = View.GONE + selectionSpinner?.onItemSelectedListener = object: AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + spinnerSelectionChanged?.invoke() + } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + spinnerSelectionChanged?.invoke() + } + }; + + } + + fun bind(title: String) { + try { + val stringID = context.resources.getIdentifier("section" + title, "string", context.packageName) + this.label.text = context.getString(stringID) + } catch (e: Exception) { + this.label.text = title + } + } + + var spinnerAdapter: ArrayAdapter? = null + set(value) { + field = value + selectionSpinner?.adapter = field + selectionSpinner?.visibility = if (value != null) View.VISIBLE else View.GONE + } + + var selectedItem: Int = 0 + get() = selectionSpinner?.selectedItemPosition ?: 0 + set(value) { + field = value + selectionSpinner?.setSelection(field) + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.java index 47a4f9f79..aaad7590d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.java @@ -101,8 +101,8 @@ public class PurchaseDialog extends AlertDialog { currencyView.setGems(user.getGemCount()); currencyView.setHourglasses(user.getHourglassCount()); - if ("gems".equals(shopItem.purchaseType)) { - int gemsLeft = shopItem.limitedNumberLeft != null ? shopItem.limitedNumberLeft : 0; + if ("gems".equals(shopItem.getPurchaseType())) { + int gemsLeft = shopItem.getLimitedNumberLeft() != null ? shopItem.getLimitedNumberLeft() : 0; int maxGems = user.getPurchased().getPlan().totalNumberOfGems(); if (maxGems > 0) { limitedTextView.setText(getContext().getString(R.string.gems_left_max, gemsLeft, maxGems)); @@ -134,7 +134,7 @@ public class PurchaseDialog extends AlertDialog { buyButton.setVisibility(View.VISIBLE); if (item.getUnlockCondition() == null) { - priceLabel.setValue(Double.valueOf(item.getValue())); + priceLabel.setValue((double) item.getValue()); priceLabel.setCurrency(item.getCurrency()); } else { setBuyButtonEnabled(false); @@ -158,7 +158,7 @@ public class PurchaseDialog extends AlertDialog { } else if (shopItem.isTypeGear()) { contentView = new PurchaseDialogGearContent(getContext()); inventoryRepository.getEquipment(item.getKey()).first().subscribe(((PurchaseDialogGearContent) contentView)::setEquipment, RxErrorHandler.handleEmptyError()); - } else if ("gems".equals(shopItem.purchaseType)) { + } else if ("gems".equals(shopItem.getPurchaseType())) { contentView = new PurchaseDialogGemsContent(getContext()); } else { contentView = new PurchaseDialogBaseContent(getContext()); @@ -209,17 +209,17 @@ public class PurchaseDialog extends AlertDialog { if (shopItem.isValid()) { if (shopItem.canBuy(user)) { Observable observable; - if ((shopIdentifier != null && shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) || "mystery_set".equals(shopItem.purchaseType)) { - if (shopItem.purchaseType.equals("gear")) { - observable = inventoryRepository.purchaseMysterySet(shopItem.categoryIdentifier); + if ((shopIdentifier != null && shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) || "mystery_set".equals(shopItem.getPurchaseType())) { + if (shopItem.getPurchaseType().equals("gear")) { + observable = inventoryRepository.purchaseMysterySet(shopItem.getCategoryIdentifier()); } else { - observable = inventoryRepository.purchaseHourglassItem(shopItem.purchaseType, shopItem.key); + observable = inventoryRepository.purchaseHourglassItem(shopItem.getPurchaseType(), shopItem.getKey()); } - } else if (shopItem.purchaseType.equals("quests") && shopItem.getCurrency().equals("gold")) { - observable = inventoryRepository.purchaseQuest(shopItem.key); - } else if ("gold".equals(shopItem.currency) && !"gem".equals(shopItem.key)) { - observable = inventoryRepository.buyItem(user, shopItem.key, shopItem.value).flatMap(buyResponse -> { - if (shopItem.key.equals("armoire")) { + } else if (shopItem.getPurchaseType().equals("quests") && shopItem.getCurrency().equals("gold")) { + observable = inventoryRepository.purchaseQuest(shopItem.getKey()); + } else if ("gold".equals(shopItem.getCurrency()) && !"gem".equals(shopItem.getKey())) { + observable = inventoryRepository.buyItem(user, shopItem.getKey(), shopItem.getValue()).flatMap(buyResponse -> { + if (shopItem.getKey().equals("armoire")) { if (buyResponse.armoire.get("type").equals("gear")) { snackbarText[0] = getContext().getString(R.string.armoireEquipment, buyResponse.armoire.get("dropText")); } else if (buyResponse.armoire.get("type").equals("food")) { @@ -231,12 +231,12 @@ public class PurchaseDialog extends AlertDialog { return Observable.just(null); }); } else { - observable = inventoryRepository.purchaseItem(shopItem.purchaseType, shopItem.key); + observable = inventoryRepository.purchaseItem(shopItem.getPurchaseType(), shopItem.getKey()); } observable .doOnNext(aVoid -> { ShowSnackbarEvent event = new ShowSnackbarEvent(); - event.title = getContext().getString(R.string.successful_purchase, shopItem.text); + event.title = getContext().getString(R.string.successful_purchase, shopItem.getText()); if (snackbarText[0].length() > 0) { event.text = snackbarText[0]; } @@ -259,11 +259,11 @@ public class PurchaseDialog extends AlertDialog { }); } else { InsufficientCurrencyDialog dialog = null; - if ("gold".equals(shopItem.currency)) { + if ("gold".equals(shopItem.getCurrency())) { dialog = new InsufficientGoldDialog(getContext()); - } else if ("gems".equals(shopItem.currency)) { + } else if ("gems".equals(shopItem.getCurrency())) { dialog = new InsufficientGemsDialog(getContext()); - } else if ("hourglasses".equals(shopItem.currency)) { + } else if ("hourglasses".equals(shopItem.getCurrency())) { dialog = new InsufficientHourglassesDialog(getContext()); } if (dialog != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java index 2bf2be119..934b5da49 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/TaskListWidgetProvider.java @@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.data.ApiClient; import com.habitrpg.android.habitica.data.TaskRepository; import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.responses.TaskDirection; import com.habitrpg.android.habitica.modules.AppModule; import com.habitrpg.android.habitica.ui.activities.MainActivity; @@ -86,7 +85,7 @@ public abstract class TaskListWidgetProvider extends BaseWidgetProvider { intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_task_list); rv.setRemoteAdapter(appWidgetId, R.id.list_view, intent); - rv.setEmptyView(R.id.list, R.id.empty_view); + rv.setEmptyView(R.id.list, R.id.emptyView); rv.setTextViewText(R.id.widget_title, context.getString(getTitleResId())); // if the user click on the title: open App