add item selling and quest inviting

This commit is contained in:
Phillip Thelen 2016-03-29 20:00:24 +02:00
parent 1506a8cd78
commit ee30133a47
24 changed files with 300 additions and 29 deletions

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
style="@style/BottomMenu"
android:clickable="false">
</LinearLayout>

View file

@ -2,9 +2,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/RowWrapper">
style="@style/BottomMenuItem"
android:clickable="true">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
style="@style/BottomMenuItemText" />
</LinearLayout>

View file

@ -67,4 +67,5 @@
<dimen name="drawer_section_item_text">12sp</dimen>
<dimen name="material_drawer_section_vertical_padding">4dp</dimen>
<dimen name="pet_width">120dp</dimen>
<dimen name="bottom_menu_padding">18dp</dimen>
</resources>

View file

@ -287,4 +287,9 @@ To start, which parts of your life do you want to improve?</string>
<string name="armoireNotesFull" formatted="false">Open the Armoire to randomly receive special Equipment, Experience, or food! Equipment pieces remaining: %d</string>
<string name="armoireLastItem">You\'ve found the last piece of rare Equipment in the Enchanted Armoire.</string>
<string name="armoireNotesEmpty">The Armoire will have new Equipment in the first week of every month. Until then, keep clicking for Experience and Food!</string>
<string name="sell" formatted="false">Sell (%s Gold)</string>
<string name="hatch_with_potion">Hatch with potion</string>
<string name="feed_to_pet">Feed to pet</string>
<string name="hatch_egg">Hatch egg</string>
<string name="invite_party">Invite party</string>
</resources>

View file

@ -156,4 +156,18 @@
<item name="android:background">@color/brand</item>
<item name="android:textColor">@color/white</item>
</style>
<style name="BottomMenu">
<item name="android:divider">?android:listDivider</item>
<item name="android:showDividers">middle</item>
</style>
<style name="BottomMenuItem">
<item name="android:padding">@dimen/bottom_menu_padding</item>
<item name="android:background">@drawable/selection_highlight</item>
</style>
<style name="BottomMenuItemText">
<item name="android:textSize">@dimen/card_medium_text</item>
</style>
</resources>

View file

@ -321,6 +321,11 @@ public class APIHelper implements ErrorHandler, Profiler {
return cause;
} else if (status == 404 && cause.getUrl().endsWith("party/chat")) {
return cause;
} else if (status == 400) {
if(res != null && res.err != null && !res.err.isEmpty()) {
showConnectionProblemDialog("", res.err);
}
return cause;
}
}
this.showConnectionProblemDialog(R.string.internal_error_api);

View file

@ -0,0 +1,6 @@
package com.habitrpg.android.habitica.events.commands;
public class InvitePartyToQuestCommand {
public String questKey;
}

View file

@ -0,0 +1,9 @@
package com.habitrpg.android.habitica.events.commands;
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Item;
public class SellItemCommand {
public Item item;
}

View file

@ -43,8 +43,10 @@ import com.habitrpg.android.habitica.events.ToggledInnStateEvent;
import com.habitrpg.android.habitica.events.commands.BuyRewardCommand;
import com.habitrpg.android.habitica.events.commands.DeleteTaskCommand;
import com.habitrpg.android.habitica.events.commands.EquipGearCommand;
import com.habitrpg.android.habitica.events.commands.InvitePartyToQuestCommand;
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand;
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
import com.habitrpg.android.habitica.events.commands.SellItemCommand;
import com.habitrpg.android.habitica.events.commands.UnlockPathCommand;
import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
@ -573,6 +575,7 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
@Subscribe
public void onEvent(UnlockPathCommand event) {
this.user.setBalance(this.user.getBalance() - event.balanceDiff);
this.setUserData(false);
mAPIHelper.apiService.unlockPath(event.path, new UnlockCallback(this, this.user));
}
@ -675,6 +678,26 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
this.displayFragment(event.fragment);
}
@Subscribe
public void onEvent(SellItemCommand event) {
String itemType = "";
this.mAPIHelper.apiService.sellItem(event.item.getType(), event.item.getKey(), new Callback<HabitRPGUser>() {
@Override
public void success(HabitRPGUser habitRPGUser, Response response) {
user.setItems(habitRPGUser.getItems());
user.save();
user.setStats(habitRPGUser.getStats());
setUserData(false);
}
@Override
public void failure(RetrofitError error) {
}
});
}
// endregion
@Override

View file

@ -3,22 +3,18 @@ package com.habitrpg.android.habitica.ui.adapter.inventory;
import android.content.Context;
import android.content.res.Resources;
import android.databinding.DataBindingUtil;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.ItemImageRowBinding;
import com.habitrpg.android.habitica.databinding.ItemItemBinding;
import com.habitrpg.android.habitica.events.commands.UseSkillCommand;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.Quest;
import com.magicmicky.habitrpgwrapper.lib.models.Skill;
import com.habitrpg.android.habitica.events.commands.InvitePartyToQuestCommand;
import com.habitrpg.android.habitica.events.commands.SellItemCommand;
import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu;
import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem;
import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuSelectionRunnable;
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Egg;
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Food;
import com.magicmicky.habitrpgwrapper.lib.models.inventory.HatchingPotion;
@ -26,18 +22,14 @@ import com.magicmicky.habitrpgwrapper.lib.models.inventory.Item;
import com.magicmicky.habitrpgwrapper.lib.models.inventory.QuestContent;
import org.greenrobot.eventbus.EventBus;
import org.w3c.dom.Text;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
public class ItemRecyclerAdapter extends RecyclerView.Adapter<ItemRecyclerAdapter.ItemViewHolder> {
private List<Item> itemList;
public Double mana;
public Boolean isHatching;
public Context context;
@ -46,12 +38,6 @@ public class ItemRecyclerAdapter extends RecyclerView.Adapter<ItemRecyclerAdapte
this.notifyDataSetChanged();
}
public void setMana(Double mana) {
this.mana = mana;
this.notifyDataSetChanged();
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
@ -88,6 +74,7 @@ public class ItemRecyclerAdapter extends RecyclerView.Adapter<ItemRecyclerAdapte
}
public void bind(Item item) {
this.item = item;
binding.setTitle(item.getText());
if (item instanceof QuestContent) {
binding.setImageNamed("inventory_quest_scroll_"+item.getKey());
@ -107,6 +94,49 @@ public class ItemRecyclerAdapter extends RecyclerView.Adapter<ItemRecyclerAdapte
@Override
public void onClick(View v) {
if (!isHatching) {
BottomSheetMenu menu = new BottomSheetMenu(context);
if (!(item instanceof QuestContent)) {
menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.sell, item.getValue()), true));
}
if (item instanceof Egg) {
menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.hatch_with_potion)));
} else if (item instanceof Food) {
menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.feed_to_pet)));
} else if (item instanceof HatchingPotion) {
menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.hatch_egg)));
} else if (item instanceof QuestContent) {
menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.invite_party)));
}
menu.setSelectionRunnable(new BottomSheetMenuSelectionRunnable() {
@Override
public void selectedItemAt(Integer index) {
if (!(item instanceof QuestContent) && index == 0) {
SellItemCommand event = new SellItemCommand();
event.item = item;
EventBus.getDefault().post(event);
if (item.getOwned() > 1) {
item.setOwned(item.getOwned()-1);
notifyItemChanged(getAdapterPosition());
} else {
itemList.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
return;
}
if (item instanceof Egg) {
} else if (item instanceof Food) {
} else if (item instanceof HatchingPotion) {
} else if (item instanceof QuestContent) {
InvitePartyToQuestCommand event = new InvitePartyToQuestCommand();
event.questKey = item.getKey();
EventBus.getDefault().post(event);
}
}
});
menu.show();
}
}
}

View file

@ -28,6 +28,7 @@ public class ItemRecyclerFragment extends BaseFragment {
public RecyclerView recyclerView;
public ItemRecyclerAdapter adapter;
public String itemType;
public Boolean isHatching;
private static final String ITEM_TYPE_KEY = "CLASS_TYPE_KEY";
LinearLayoutManager layoutManager = null;
@ -54,6 +55,7 @@ public class ItemRecyclerFragment extends BaseFragment {
if (adapter == null) {
adapter = new ItemRecyclerAdapter();
adapter.context = this.getActivity();
adapter.isHatching = this.isHatching;
recyclerView.setAdapter(adapter);
this.loadItems();

View file

@ -10,9 +10,20 @@ import android.view.ViewGroup;
import com.habitrpg.android.habitica.ContentCache;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.events.commands.InvitePartyToQuestCommand;
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
import com.habitrpg.android.habitica.ui.MainDrawerBuilder;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.UserParty;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class ItemsFragment extends BaseMainFragment {
public ViewPager viewPager;
@ -67,6 +78,7 @@ public class ItemsFragment extends BaseMainFragment {
break;
}
}
fragment.isHatching = false;
return fragment;
}
@ -94,4 +106,21 @@ public class ItemsFragment extends BaseMainFragment {
tabLayout.setupWithViewPager(viewPager);
}
@Subscribe
public void onEvent(InvitePartyToQuestCommand event) {
this.mAPIHelper.apiService.inviteToQuest("party", event.questKey, new Callback<Group>() {
@Override
public void success(Group group, Response response) {
OpenMenuItemCommand event = new OpenMenuItemCommand();
event.identifier = MainDrawerBuilder.SIDEBAR_PARTY;
EventBus.getDefault().post(event);
}
@Override
public void failure(RetrofitError error) {
}
});
}
}

View file

@ -0,0 +1,61 @@
package com.habitrpg.android.habitica.ui.menu;
import android.content.Context;
import android.support.design.widget.BottomSheetDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import org.w3c.dom.Text;
import java.util.ArrayList;
public class BottomSheetMenu extends BottomSheetDialog implements View.OnClickListener {
private LayoutInflater inflater;
private Context context;
private LinearLayout contentView;
private BottomSheetMenuSelectionRunnable runnable;
public BottomSheetMenu(Context context) {
super(context);
this.context = context;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.contentView = (LinearLayout)inflater.inflate(R.layout.menu_bottom_sheet, null);
this.setContentView(this.contentView);
}
public void setSelectionRunnable(BottomSheetMenuSelectionRunnable runnable) {
this.runnable = runnable;
}
public void addMenuItems(BottomSheetMenuItem... menuItems) {
for (BottomSheetMenuItem menuItem : menuItems) {
this.addMenuItem(menuItem);
}
}
public void addMenuItem(BottomSheetMenuItem menuItem) {
View item = menuItem.inflate(this.context, this.inflater, this.contentView);
item.setOnClickListener(this);
this.contentView.addView(item);
}
public void removeMenuItem(Integer index) {
this.contentView.removeViewAt(index);
}
@Override
public void onClick(View v) {
if (this.runnable != null) {
Integer index = this.contentView.indexOfChild(v);
if (index != -1) {
this.runnable.selectedItemAt(index);
this.dismiss();
}
}
}
}

View file

@ -0,0 +1,37 @@
package com.habitrpg.android.habitica.ui.menu;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
public class BottomSheetMenuItem {
private String title;
private Boolean isDestructive;
public BottomSheetMenuItem(String title) {
this.title = title;
this.isDestructive = false;
}
public BottomSheetMenuItem(String title, Boolean isDestructive) {
this.title = title;
this.isDestructive = isDestructive;
}
public View inflate(Context context, LayoutInflater inflater, ViewGroup contentView) {
LinearLayout menuItemView = (LinearLayout)inflater.inflate(R.layout.menu_bottom_sheet_item, contentView, false);
TextView textView = (TextView)menuItemView.findViewById(R.id.textView);
textView.setText(this.title);
if (this.isDestructive) {
textView.setTextColor(context.getResources().getColor(R.color.worse_50));
}
return menuItemView;
}
}

View file

@ -0,0 +1,9 @@
package com.habitrpg.android.habitica.ui.menu;
import android.graphics.Bitmap;
public interface BottomSheetMenuSelectionRunnable {
void selectedItemAt(Integer index);
}

View file

@ -2,9 +2,6 @@ package com.habitrpg.android.habitica.userpicture;
import android.graphics.Bitmap;
/**
* Created by viirus on 16/11/15.
*/
public interface UserPictureRunnable {
void run(Bitmap avatarBitmap);

View file

@ -60,6 +60,9 @@ public interface ApiService {
@POST("/user/inventory/buy/{key}")
void buyItem(@Path("key") String itemKey, Callback<BuyResponse> voidCallback);
@POST("/user/inventory/sell/{type}/{key}")
void sellItem(@Path("type") String itemType, @Path("key") String itemKey, Callback<HabitRPGUser> voidCallback);
@POST("/user/unlock")
void unlockPath(@Query("path") String path, Callback<UnlockResponse> unlockResponseCallback);
@ -164,6 +167,8 @@ public interface ApiService {
@POST("/groups/{gid}/questAccept?force=true")
void forceStartQuest(@Path("gid") String groupId, @Body Group group, Callback<Group> cb);
@POST("/groups/{gid}/questAccept")
void inviteToQuest(@Path("gid") String groupId, @Query("key") String questKey, Callback<Group> cb);
@POST("/groups/{gid}/questAbort")
void abortQuest(@Path("gid") String groupId, Callback<Group> cb);

View file

@ -12,8 +12,12 @@ import com.raizlabs.android.dbflow.annotation.ForeignKeyReference;
import com.raizlabs.android.dbflow.annotation.NotNull;
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.runtime.TransactionManager;
import com.raizlabs.android.dbflow.runtime.transaction.process.ProcessModelInfo;
import com.raizlabs.android.dbflow.runtime.transaction.process.SaveModelTransaction;
import com.raizlabs.android.dbflow.structure.BaseModel;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -164,6 +168,13 @@ public class Items extends BaseModel {
public void save() {
gear.user_id = user_id;
List<BaseModel> items = new ArrayList<>();
items.addAll(this.quests);
items.addAll(this.eggs);
items.addAll(this.food);
items.addAll(this.hatchingPotions);
TransactionManager.getInstance().addTransaction(new SaveModelTransaction<>(ProcessModelInfo.withModels(items)));
super.save();
}
}

View file

@ -46,4 +46,9 @@ public class Egg extends Item {
public void setStableTotal(Integer stableTotal) {
this.stableTotal = stableTotal;
}
@Override
public String getType() {
return "eggs";
}
}

View file

@ -36,4 +36,8 @@ public class Food extends Item {
public void setCanDrop(Boolean canDrop) {
this.canDrop = canDrop;
}
public String getType() {
return "food";
}
}

View file

@ -25,4 +25,9 @@ public class HatchingPotion extends Item {
public void setPremium(Boolean premium) {
this.premium = premium;
}
@Override
public String getType() {
return "hatchingPotions";
}
}

View file

@ -6,7 +6,7 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.raizlabs.android.dbflow.structure.BaseModel;
public class Item extends BaseModel {
public abstract class Item extends BaseModel {
@Column
@PrimaryKey
@ -57,4 +57,6 @@ public class Item extends BaseModel {
public void setOwned(Integer owned) {
this.owned = owned;
}
public abstract String getType();
}

View file

@ -106,4 +106,8 @@ public class QuestContent extends Item {
super.save();
}
@Override
public String getType() {
return "quests";
}
}

View file

@ -1,5 +1,6 @@
package com.magicmicky.habitrpgwrapper.lib.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@ -46,7 +47,10 @@ public class GroupSerialization implements JsonDeserializer<Group>, JsonSerializ
}.getType());
}
if (obj.has("members")) {
group.members = context.deserialize(obj.get("members"), new TypeToken<List<HabitRPGUser>>(){}.getType());
JsonArray memberList = obj.get("members").getAsJsonArray();
if (memberList.size() > 0 && memberList.get(0).isJsonObject()) {
group.members = context.deserialize(memberList, new TypeToken<List<HabitRPGUser>>(){}.getType());
}
}
if (obj.has("leader")) {
if (obj.get("leader").isJsonPrimitive()) {