Reimplement purchasing

This commit is contained in:
Phillip Thelen 2017-07-25 19:05:33 +02:00
parent aae43575e6
commit e455677da9
11 changed files with 136 additions and 59 deletions

View file

@ -118,7 +118,8 @@
android:layout_marginBottom="8dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:gravity="center_vertical">
<RatingBar
android:id="@+id/quest_difficulty_view"
android:layout_width="wrap_content"

View file

@ -399,7 +399,7 @@
<string name="party_invite">Unlock by inviting friends</string>
<string name="no_gold">Not enough Gold</string>
<string name="no_potion">You don\'t need to buy an health potion</string>
<string name="successful_purchase" >%1$s successfully purchased</string>
<string name="successful_purchase" >Purchased %1$s</string>
<string name="purchase_confirmation_title">Confirm purchase</string>
<string name="confirm_purchase_text" >Purchase %1$s for %2$s %3$s</string>
<string name="gem">gem</string>

View file

@ -13,6 +13,7 @@ import com.habitrpg.android.habitica.models.inventory.Quest;
import com.habitrpg.android.habitica.models.inventory.QuestContent;
import com.habitrpg.android.habitica.models.responses.BuyResponse;
import com.habitrpg.android.habitica.models.responses.FeedResponse;
import com.habitrpg.android.habitica.models.shops.Shop;
import com.habitrpg.android.habitica.models.user.Items;
import com.habitrpg.android.habitica.models.user.User;
@ -71,4 +72,14 @@ public interface InventoryRepository extends ContentRepository {
Observable<Quest> inviteToQuest(QuestContent quest);
Observable<BuyResponse> buyItem(User user, String id, double value);
Observable<Shop> fetchShopInventory(String identifier);
Observable<Void> purchaseMysterySet(String categoryIdentifier);
Observable<Void> purchaseHourglassItem(String purchaseType, String key);
Observable<Void> purchaseQuest(String key);
Observable<Void> purchaseItem(String purchaseType, String key);
}

View file

@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.models.inventory.Quest;
import com.habitrpg.android.habitica.models.inventory.QuestContent;
import com.habitrpg.android.habitica.models.responses.BuyResponse;
import com.habitrpg.android.habitica.models.responses.FeedResponse;
import com.habitrpg.android.habitica.models.shops.Shop;
import com.habitrpg.android.habitica.models.user.Items;
import com.habitrpg.android.habitica.models.user.Outfit;
import com.habitrpg.android.habitica.models.user.Stats;
@ -243,4 +244,29 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl<InventoryLoca
localRepository.save(copiedUser);
}));
}
@Override
public Observable<Shop> fetchShopInventory(String identifier) {
return apiClient.fetchShopInventory(identifier);
}
@Override
public Observable<Void> purchaseMysterySet(String categoryIdentifier) {
return apiClient.purchaseMysterySet(categoryIdentifier);
}
@Override
public Observable<Void> purchaseHourglassItem(String purchaseType, String key) {
return apiClient.purchaseHourglassItem(purchaseType, key);
}
@Override
public Observable<Void> purchaseQuest(String key) {
return apiClient.purchaseQuest(key);
}
@Override
public Observable<Void> purchaseItem(String purchaseType, String key) {
return apiClient.purchaseItem(purchaseType, key);
}
}

View file

@ -67,7 +67,7 @@ public class Shop {
return R.string.questShop_owner;
case "seasonalShop":
return R.string.seasonalShop_owner;
case "timetravelersShop":
case "timeTravelersShop":
return R.string.timetravelers_owner;
default:
return R.string.market_owner;

View file

@ -557,35 +557,6 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria
}
}
@Subscribe
public void onEvent(final BuyGemItemCommand event) {
if (event.item.canBuy(user) || !event.item.getCurrency().equals("gems")) {
Observable<Void> observable;
if (event.shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) {
if (event.item.purchaseType.equals("gear")) {
observable = apiClient.purchaseMysterySet(event.item.categoryIdentifier);
} else {
observable = apiClient.purchaseHourglassItem(event.item.purchaseType, event.item.key);
}
} else if (event.item.purchaseType.equals("quests") && event.item.getCurrency().equals("gold")) {
observable = apiClient.purchaseQuest(event.item.key);
} else {
observable = apiClient.purchaseItem(event.item.purchaseType, event.item.key);
}
observable
.doOnNext(aVoid -> showSnackbar(this, floatingMenuWrapper, getString(R.string.successful_purchase, event.item.text), SnackbarDisplayType.NORMAL))
.flatMap(buyResponse -> userRepository.retrieveUser(false))
.subscribe(buyResponse -> {}, throwable -> {
retrofit2.HttpException error = (retrofit2.HttpException) throwable;
if (error.code() == 401 && event.item.getCurrency().equals("gems")) {
openGemPurchaseFragment(null);
}
});
} else {
openGemPurchaseFragment(null);
}
}
@Subscribe
public void onEvent(final BuyRewardCommand event) {
final String rewardKey = event.Reward.getId();

View file

@ -49,6 +49,9 @@ import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.Subscription;
import rx.subjects.PublishSubject;
public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -169,13 +172,6 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
itemView.setClickable(true);
}
private void buyItem() {
BuyGemItemCommand command = new BuyGemItemCommand();
command.shopIdentifier = shopIdentifier;
command.item = item;
EventBus.getDefault().post(command);
}
public void bind(ShopItem item) {
this.item = item;
buyButton.setVisibility(View.VISIBLE);
@ -223,6 +219,7 @@ public class ShopRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
@Override
public void onClick(View view) {
PurchaseDialog dialog = new PurchaseDialog(context, HabiticaBaseApplication.getComponent(), item);
dialog.shopIdentifier = shopIdentifier;
dialog.show();
}
}

View file

@ -11,14 +11,21 @@ import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.components.AppComponent;
import com.habitrpg.android.habitica.data.ApiClient;
import com.habitrpg.android.habitica.data.InventoryRepository;
import com.habitrpg.android.habitica.data.UserRepository;
import com.habitrpg.android.habitica.events.commands.BuyGemItemCommand;
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.activities.MainActivity;
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.views.HabiticaSnackbar;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
@ -26,6 +33,9 @@ import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import static com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.showSnackbar;
public class ShopFragment extends BaseFragment {
private static final String SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY";
@ -39,7 +49,9 @@ public class ShopFragment extends BaseFragment {
public User user;
public Shop shop;
@Inject
ApiClient apiClient;
InventoryRepository inventoryRepository;
@Inject
UserRepository userRepository;
private View view;
private GridLayoutManager layoutManager;
@ -89,6 +101,13 @@ public class ShopFragment extends BaseFragment {
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);
@ -112,7 +131,7 @@ public class ShopFragment extends BaseFragment {
shopUrl = "seasonal";
break;
}
this.apiClient.fetchShopInventory(shopUrl)
this.inventoryRepository.fetchShopInventory(shopUrl)
.map(shop1 -> {
if (shop1.identifier.equals(Shop.MARKET)) {
if (user.getPurchased().getPlan().isActive()) {
@ -155,4 +174,5 @@ public class ShopFragment extends BaseFragment {
layoutManager.setSpanCount(spanCount);
layoutManager.requestLayout();
}
}

View file

@ -6,21 +6,33 @@ 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.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
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.events.commands.BuyGemItemCommand;
import com.habitrpg.android.habitica.models.shops.Shop;
import com.habitrpg.android.habitica.models.user.User;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.habitrpg.android.habitica.ui.views.CurrencyView;
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar;
import org.greenrobot.eventbus.Subscribe;
import javax.inject.Inject;
import rx.Observable;
import static com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.showSnackbar;
public class ShopsFragment extends BaseMainFragment {
@Inject
InventoryRepository inventoryRepository;
public ViewPager viewPager;
private CurrencyView currencyView;
@ -59,6 +71,7 @@ public class ShopsFragment extends BaseMainFragment {
}
showToolbar();
enableToolbarScrolling();
inventoryRepository.close();
super.onDestroyView();
}
@ -109,13 +122,13 @@ public class ShopsFragment extends BaseMainFragment {
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return activity.getString(R.string.market);
return getContext().getString(R.string.market);
case 1:
return activity.getString(R.string.quests);
return getContext().getString(R.string.quests);
case 2:
return activity.getString(R.string.timeTravelers);
return getContext().getString(R.string.timeTravelers);
case 3:
return activity.getString(R.string.seasonalShop);
return getContext().getString(R.string.seasonalShop);
}
return "";
}
@ -150,4 +163,34 @@ public class ShopsFragment extends BaseMainFragment {
currencyView.setGems(user.getGemCount());
currencyView.setHourglasses(user.getHourglassCount());
}
@Subscribe
public void onEvent(final BuyGemItemCommand event) {
MainActivity activity = (MainActivity) getActivity();
if (event.item.canBuy(user) || !event.item.getCurrency().equals("gems")) {
Observable<Void> observable;
if (event.shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) {
if (event.item.purchaseType.equals("gear")) {
observable = inventoryRepository.purchaseMysterySet(event.item.categoryIdentifier);
} else {
observable = inventoryRepository.purchaseHourglassItem(event.item.purchaseType, event.item.key);
}
} else if (event.item.purchaseType.equals("quests") && event.item.getCurrency().equals("gold")) {
observable = inventoryRepository.purchaseQuest(event.item.key);
} else {
observable = inventoryRepository.purchaseItem(event.item.purchaseType, event.item.key);
}
observable
.doOnNext(aVoid -> showSnackbar(getContext(), activity.floatingMenuWrapper, getString(R.string.successful_purchase, event.item.text), HabiticaSnackbar.SnackbarDisplayType.SUCCESS))
.flatMap(buyResponse -> userRepository.retrieveUser(false))
.subscribe(buyResponse -> {}, throwable -> {
retrofit2.HttpException error = (retrofit2.HttpException) throwable;
if (error.code() == 401 && event.item.getCurrency().equals("gems")) {
activity.openGemPurchaseFragment(null);
}
});
} else {
activity.openGemPurchaseFragment(null);
}
}
}

View file

@ -18,10 +18,6 @@ import com.habitrpg.android.habitica.R;
import javax.annotation.Resource;
/**
* Created by phillip on 04.07.17.
*/
public class HabiticaSnackbar extends BaseTransientBottomBar<HabiticaSnackbar> {
/**
@ -35,7 +31,7 @@ public class HabiticaSnackbar extends BaseTransientBottomBar<HabiticaSnackbar> {
super(parent, content, callback);
}
public static HabiticaSnackbar make(@NonNull ViewGroup parent, int duration) {
private static HabiticaSnackbar make(@NonNull ViewGroup parent, int duration) {
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final View content = inflater.inflate(R.layout.snackbar_view, parent, false);
final ContentViewCallback viewCallback = new ContentViewCallback(content);
@ -70,7 +66,7 @@ public class HabiticaSnackbar extends BaseTransientBottomBar<HabiticaSnackbar> {
return this;
}
public HabiticaSnackbar setSpecialView(View specialView) {
private HabiticaSnackbar setSpecialView(View specialView) {
if (specialView != null) {
LinearLayout snackbarView = (LinearLayout) getView().findViewById(R.id.snackbar_view);
snackbarView.addView(specialView);
@ -133,6 +129,7 @@ public class HabiticaSnackbar extends BaseTransientBottomBar<HabiticaSnackbar> {
snackbar.setBackgroundResource(R.drawable.snackbar_background_blue);
break;
case NORMAL:
case SUCCESS:
snackbar.setBackgroundResource(R.drawable.snackbar_background_green);
break;
}
@ -141,7 +138,7 @@ public class HabiticaSnackbar extends BaseTransientBottomBar<HabiticaSnackbar> {
}
public enum SnackbarDisplayType {
NORMAL, FAILURE, FAILURE_BLUE, DROP, BLUE
NORMAL, FAILURE, FAILURE_BLUE, DROP, SUCCESS, BLUE
}
}

View file

@ -1,6 +1,5 @@
package com.habitrpg.android.habitica.ui.views.shops;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.support.v4.content.ContextCompat;
@ -16,12 +15,14 @@ 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.events.commands.BuyGemItemCommand;
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
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.views.CurrencyView;
import org.greenrobot.eventbus.EventBus;
import java.util.Date;
import javax.inject.Inject;
@ -55,9 +56,10 @@ public class PurchaseDialog extends AlertDialog {
private ShopItem shopItem;
PurchaseDialogContent contentView;
private PurchaseDialogContent contentView;
CompositeSubscription compositeSubscription;
private CompositeSubscription compositeSubscription;
public String shopIdentifier;
public PurchaseDialog(Context context, AppComponent component, ShopItem item) {
super(context);
@ -184,6 +186,15 @@ public class PurchaseDialog extends AlertDialog {
dismiss();
}
@OnClick(R.id.buyButton)
void onBuyButtonClicked() {
BuyGemItemCommand event = new BuyGemItemCommand();
event.shopIdentifier = shopIdentifier;
event.item = shopItem;
EventBus.getDefault().post(event);
dismiss();
}
public void setBuyButtonEnabled(boolean enabled) {
if (enabled) {
buyButton.setAlpha(0.5f);