From ae08141d9552e64efc21022c2605618aecdb8574 Mon Sep 17 00:00:00 2001 From: Negue Date: Wed, 15 Jul 2015 15:36:12 +0200 Subject: [PATCH] - Load content / ItemData & save to DB - Load buy-able gear & list it - buy potion / gear / rewards --- .../habitrpg/android/habitica/APIHelper.java | 7 +- .../android/habitica/MainActivity.java | 160 +++++++++++++++++- .../callbacks/HabitRPGUserCallback.java | 3 +- .../adapter/HabitItemRecyclerViewAdapter.java | 66 +++++++- .../fragments/TaskRecyclerViewFragment.java | 13 +- .../habitrpgwrapper/lib/api/ApiService.java | 15 +- .../lib/models/ContentGear.java | 11 ++ .../lib/models/ContentResult.java | 16 ++ .../lib/models/tasks/ItemData.java | 45 +++++ .../lib/models/tasks/RewardItem.java | 8 + 10 files changed, 321 insertions(+), 23 deletions(-) create mode 100644 Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentGear.java create mode 100644 Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentResult.java create mode 100644 Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/ItemData.java create mode 100644 Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/RewardItem.java diff --git a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java index 5960532d0..2103fdd1d 100644 --- a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java +++ b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java @@ -46,7 +46,8 @@ import retrofit.converter.GsonConverter; public class APIHelper implements ErrorHandler, Profiler { private static final String TAG = "ApiHelper"; - private final ApiService apiService; + // I think we don't need the APIHelper anymore we could just use ApiService + public final ApiService apiService; private Context mContext; //private OnHabitsAPIResult mResultListener; //private HostConfig mConfig; @@ -199,10 +200,10 @@ public class APIHelper implements ErrorHandler, Profiler { } - public void buyItem(Reward.SpecialReward itemBought, View btn) { + //public void buyItem(Reward.SpecialReward itemBought, View btn) { // ATaskBuyItem buyItem = new ATaskBuyItem(mResultListener,btn, mConfig); // buyItem.execute(itemBought); - } + //} public void changeTimeZone(int timeZoneOffset) { // ATaskChangeTimeZone changeTimeZone= new ATaskChangeTimeZone(mResultListener,mConfig); // changeTimeZone.execute(timeZoneOffset); diff --git a/Habitica/src/com/habitrpg/android/habitica/MainActivity.java b/Habitica/src/com/habitrpg/android/habitica/MainActivity.java index fea2e888f..e5259b6ae 100644 --- a/Habitica/src/com/habitrpg/android/habitica/MainActivity.java +++ b/Habitica/src/com/habitrpg/android/habitica/MainActivity.java @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica; import android.content.Intent; +import android.databinding.ObservableArrayList; import android.graphics.Color; import android.os.Bundle; import android.support.design.widget.Snackbar; @@ -29,6 +30,7 @@ import com.habitrpg.android.habitica.ui.EditTextDrawer; import com.habitrpg.android.habitica.ui.adapter.HabitItemRecyclerViewAdapter; import com.habitrpg.android.habitica.ui.fragments.TaskRecyclerViewFragment; import com.instabug.wrapper.support.activity.InstabugAppCompatActivity; +import com.magicmicky.habitrpgwrapper.lib.models.ContentResult; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; import com.magicmicky.habitrpgwrapper.lib.models.Tag; import com.magicmicky.habitrpgwrapper.lib.models.TaskDirection; @@ -36,7 +38,9 @@ import com.magicmicky.habitrpgwrapper.lib.models.TaskDirectionData; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Daily; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Habit; import com.magicmicky.habitrpgwrapper.lib.models.tasks.HabitItem; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Reward; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.RewardItem; import com.magicmicky.habitrpgwrapper.lib.models.tasks.ToDo; import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.DrawerBuilder; @@ -47,6 +51,8 @@ import com.mikepenz.materialdrawer.model.SectionDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.raizlabs.android.dbflow.runtime.FlowContentObserver; import com.raizlabs.android.dbflow.sql.builder.Condition; +import com.raizlabs.android.dbflow.sql.builder.ConditionQueryBuilder; +import com.raizlabs.android.dbflow.sql.language.ColumnAlias; import com.raizlabs.android.dbflow.sql.language.Select; import com.raizlabs.android.dbflow.structure.BaseModel; import com.raizlabs.android.dbflow.structure.Model; @@ -65,8 +71,9 @@ import retrofit.RetrofitError; import retrofit.client.Response; public class MainActivity extends InstabugAppCompatActivity implements HabitRPGUserCallback.OnUserReceived, - TaskScoringCallback.OnTaskScored, Callback, OnTaskCreationListener, - FlowContentObserver.OnSpecificModelStateChangedListener, TaskCreationCallback.OnHabitCreated, TaskUpdateCallback.OnHabitUpdated { + TaskScoringCallback.OnTaskScored, OnTaskCreationListener, + FlowContentObserver.OnSpecificModelStateChangedListener, TaskCreationCallback.OnHabitCreated, TaskUpdateCallback.OnHabitUpdated, + Callback> { static final int SETTINGS = 11; static final int ABOUT = 12; @@ -225,9 +232,16 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU this.observer.addSpecificModelChangeListener(this); + try { + hasItemData = new Select().from(ItemData.class).querySingle() != null; + } catch (Exception e) { + + } SetUserData(false); } + private boolean hasItemData = false; + @Override protected void onResume() { super.onResume(); @@ -297,8 +311,52 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU dialog.show(getSupportFragmentManager(), "AddTaskDialog"); } - public void onEvent(BuyRewardTappedEvent event) { - showSnackbar("Buy Reward " + event.Reward.getText()); + public void onEvent(final BuyRewardTappedEvent event) { + final String rewardKey = event.Reward.getId(); + + if (User.getStats().getGp() < event.Reward.getValue()) { + showSnackbar("Not enough Gold", true); + return; + } + + if (event.Reward instanceof RewardItem) { + if (rewardKey.equals("potion")) { + int currentHp = User.getStats().getHp().intValue(); + int maxHp = User.getStats().getMaxHealth(); + + if(currentHp == maxHp) { + showSnackbar("You don't need to buy an health potion", true); + return; + } + } + + mAPIHelper.apiService.buyItem(event.Reward.getId(), new Callback() { + @Override + public void success(Void aVoid, Response response) { + + switch (rewardKey) { + case "potion": + double newHp = Math.min(User.getStats().getMaxHealth(), User.getStats().getHp() + 15); + User.getStats().setHp(newHp); + + updateHeader(); + + break; + } + + showSnackbar("Buy Reward Successful " + event.Reward.getText()); + } + + @Override + public void failure(RetrofitError error) { + + showSnackbar("Buy Reward Error " + event.Reward.getText(), true); + } + }); + } else { + // User created Rewards + mAPIHelper.updateTaskDirection(rewardKey, TaskDirection.down, new TaskScoringCallback(this)); + } } private void notifyUser(double xp, double hp, double gold, @@ -340,8 +398,11 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU static public Double round(Double value, int n) { double r = (Math.round(value.doubleValue() * Math.pow(10, n))) / (Math.pow(10, n)); return Double.valueOf(r); + } + private ObservableArrayList GearRewards = new ObservableArrayList<>(); + public void loadTaskLists() { android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); @@ -371,6 +432,11 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU layoutOfType = R.layout.reward_item_card; fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Reward.class, layoutOfType, HabitItemRecyclerViewAdapter.RewardViewHolder.class, context), Reward.class); break; + case 4: + layoutOfType = R.layout.reward_item_card; + fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Reward.class, layoutOfType, HabitItemRecyclerViewAdapter.RewardViewHolder.class, + context, GearRewards), Reward.class, false); + break; default: layoutOfType = R.layout.todo_item_card; fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(ToDo.class, layoutOfType, HabitItemRecyclerViewAdapter.TodoViewHolder.class, context), ToDo.class); @@ -383,7 +449,7 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU @Override public int getCount() { - return 4; + return 5; } @Override @@ -397,6 +463,8 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU return "Todos"; case 3: return "Rewards"; + case 4: + return "Gear"; } return ""; } @@ -461,7 +529,17 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU return true; case R.id.action_toggle_sleep: - mAPIHelper.toggleSleep(this); + mAPIHelper.toggleSleep(new Callback() { + @Override + public void success(Void aVoid, Response response) { + + } + + @Override + public void failure(RetrofitError error) { + + } + }); User.getPreferences().setSleep(!User.getPreferences().getSleep()); @@ -497,9 +575,40 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU } - @Override - public void success(Void aVoid, Response response) { + @Override + public void success(List items, Response response) { + + // TODO Order Rewards + // TODO add Gear Images + + Condition.In keyCondition = Condition.column("key").in("potion"); + + for (ItemData item : items) { + keyCondition = keyCondition.and(item.key); + } + + + ConditionQueryBuilder queryBuilder = new ConditionQueryBuilder(ItemData.class, + keyCondition); + + List itemsFromDb = new Select().from(ItemData.class).where(queryBuilder).queryList(); + + ArrayList rewardList = new ArrayList(); + + + for (ItemData item : itemsFromDb) { + Reward reward = new RewardItem(); + reward.text = item.text; + reward.notes = item.notes; + reward.value = item.value; + reward.setId(item.key); + + rewardList.add(reward); + } + + GearRewards.clear(); + GearRewards.addAll(rewardList); } @Override @@ -526,6 +635,8 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU private boolean taskListAlreadyAdded; + private boolean getContentCalled = false; + private void SetUserData(final boolean onlyHeader) { if (User != null) { runOnUiThread(new Runnable() { @@ -539,6 +650,39 @@ public class MainActivity extends InstabugAppCompatActivity implements HabitRPGU updateHeader(); } }); + + + if (mAPIHelper != null && !getContentCalled && !hasItemData) { + getContentCalled = true; + mAPIHelper.apiService.getContent(new Callback() { + @Override + public void success(ContentResult contentResult, Response response) { + ArrayList list = new ArrayList<>(); + list.add(contentResult.potion); + list.add(contentResult.armoire); + list.addAll(contentResult.gear.flat.values()); + + for (ItemData itemData : list) { + itemData.save(); + } + + hasItemData = true; + + mAPIHelper.apiService.getInventoryBuyableGear(MainActivity.this); + } + + @Override + public void failure(RetrofitError error) { + + } + }); + + + } + + if (mAPIHelper != null && hasItemData) { + mAPIHelper.apiService.getInventoryBuyableGear(this); + } } } diff --git a/Habitica/src/com/habitrpg/android/habitica/callbacks/HabitRPGUserCallback.java b/Habitica/src/com/habitrpg/android/habitica/callbacks/HabitRPGUserCallback.java index 857cd400c..4f0a511de 100644 --- a/Habitica/src/com/habitrpg/android/habitica/callbacks/HabitRPGUserCallback.java +++ b/Habitica/src/com/habitrpg/android/habitica/callbacks/HabitRPGUserCallback.java @@ -21,8 +21,9 @@ public class HabitRPGUserCallback implements Callback { } @Override public void success(HabitRPGUser habitRPGUser, Response response) { - mCallback.onUserReceived(habitRPGUser); habitRPGUser.save(); + + mCallback.onUserReceived(habitRPGUser); } @Override diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/HabitItemRecyclerViewAdapter.java b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/HabitItemRecyclerViewAdapter.java index dc6607736..53df1398a 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/HabitItemRecyclerViewAdapter.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/HabitItemRecyclerViewAdapter.java @@ -2,6 +2,8 @@ package com.habitrpg.android.habitica.ui.adapter; import android.content.Context; import android.databinding.DataBindingUtil; +import android.databinding.ObservableArrayList; +import android.databinding.ObservableList; import android.os.Handler; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; @@ -50,6 +52,7 @@ public class HabitItemRecyclerViewAdapter private Class> viewHolderClass; List contents; Class taskClass; + private ObservableArrayList observableContent; FlowContentObserver observer; Context context; @@ -59,15 +62,61 @@ public class HabitItemRecyclerViewAdapter public HabitItemRecyclerViewAdapter(Class newTaskClass, int layoutResource, Class> viewHolderClass, Context newContext) { + this(newTaskClass, layoutResource, viewHolderClass, newContext, null); + } + + public HabitItemRecyclerViewAdapter(Class newTaskClass, int layoutResource, Class> viewHolderClass, + Context newContext, final ObservableArrayList content) { this.context = newContext; this.taskClass = newTaskClass; - this.loadContent(); + observableContent = content; - observer = new FlowContentObserver(); - observer.registerForContentChanges(this.context, this.taskClass); + if(content == null) + { + this.loadContent(); - observer.addSpecificModelChangeListener(this); + observer = new FlowContentObserver(); + observer.registerForContentChanges(this.context, this.taskClass); + + observer.addSpecificModelChangeListener(this); + } + else + { + content.addOnListChangedCallback(new ObservableList.OnListChangedCallback() { + @Override + public void onChanged(ObservableList sender) { + handler.removeCallbacks(reloadContentRunable); + handler.postDelayed(reloadContentRunable, 200); + } + + @Override + public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) { + handler.removeCallbacks(reloadContentRunable); + handler.postDelayed(reloadContentRunable, 200); + } + + @Override + public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) { + handler.removeCallbacks(reloadContentRunable); + handler.postDelayed(reloadContentRunable, 200); + } + + @Override + public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) { + handler.removeCallbacks(reloadContentRunable); + handler.postDelayed(reloadContentRunable, 200); + } + + @Override + public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) { + handler.removeCallbacks(reloadContentRunable); + handler.postDelayed(reloadContentRunable, 200); + } + }); + + loadContent(); + } this.layoutResource = layoutResource; this.viewHolderClass = viewHolderClass; @@ -357,7 +406,14 @@ public class HabitItemRecyclerViewAdapter } public void loadContent() { - this.contents = new Select().from(this.taskClass).queryList(); + if(this.observableContent == null) { + + this.contents = new Select().from(this.taskClass).queryList(); + } + else + { + this.contents = observableContent; + } if(parentAdapter != null) { diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/TaskRecyclerViewFragment.java b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/TaskRecyclerViewFragment.java index 1eeae5b52..29c3ec1b0 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/TaskRecyclerViewFragment.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/TaskRecyclerViewFragment.java @@ -35,9 +35,12 @@ public class TaskRecyclerViewFragment extends Fragment implements View.OnClickLi public RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; private Class classType; + private boolean showFloatingButton; - public void SetInnerAdapter(HabitItemRecyclerViewAdapter adapter, Class classType) { + // TODO needs a bit of cleanup + public void SetInnerAdapter(HabitItemRecyclerViewAdapter adapter, Class classType, boolean showFloatingButton) { this.classType = classType; + this.showFloatingButton = showFloatingButton; mAdapter = new RecyclerViewMaterialAdapter(adapter); adapter.setParentAdapter(mAdapter); } @@ -76,6 +79,8 @@ public class TaskRecyclerViewFragment extends Fragment implements View.OnClickLi fab.setClickable(true); } + fab.setVisibility(showFloatingButton ? View.VISIBLE : View.INVISIBLE); + layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager(); if (layoutManager == null) { @@ -94,9 +99,13 @@ public class TaskRecyclerViewFragment extends Fragment implements View.OnClickLi } public static TaskRecyclerViewFragment newInstance(HabitItemRecyclerViewAdapter adapter, Class classType) { + return newInstance(adapter, classType, true); + } + + public static TaskRecyclerViewFragment newInstance(HabitItemRecyclerViewAdapter adapter, Class classType, boolean showFloatingButton) { TaskRecyclerViewFragment fragment = new TaskRecyclerViewFragment(); - fragment.SetInnerAdapter(adapter, classType); + fragment.SetInnerAdapter(adapter, classType,showFloatingButton); Log.d("TaskRecyclerViewFragment", "newInstance"); diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java index b6aaf263c..086b8c15c 100644 --- a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java @@ -1,15 +1,15 @@ package com.magicmicky.habitrpgwrapper.lib.api; +import com.magicmicky.habitrpgwrapper.lib.models.ContentResult; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; import com.magicmicky.habitrpgwrapper.lib.models.Status; import com.magicmicky.habitrpgwrapper.lib.models.Tag; -import com.magicmicky.habitrpgwrapper.lib.models.TaskDirection; import com.magicmicky.habitrpgwrapper.lib.models.TaskDirectionData; import com.magicmicky.habitrpgwrapper.lib.models.UserAuth; import com.magicmicky.habitrpgwrapper.lib.models.UserAuthResponse; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Daily; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Habit; -import com.magicmicky.habitrpgwrapper.lib.models.tasks.HabitItem; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Reward; import com.magicmicky.habitrpgwrapper.lib.models.tasks.ToDo; @@ -34,6 +34,14 @@ public interface ApiService { @GET("/user/") void getUser(Callback habitRPGUserCallback); + @GET("/user/inventory/buy") + void getInventoryBuyableGear(Callback> buyableGearCallback); + + @GET("/content") + void getContent(Callback contentResultCallback); + + @POST("/user/inventory/buy/{key}") + void buyItem(@Path("key") String itemKey, Callback voidCallback); // @POST("/user/revive") // void revive(Callback habitRPGUserCallback); @@ -100,8 +108,7 @@ public interface ApiService { - @POST("/user/inventory/buy/{key}") - void buyItem(@Path("key") String itemKey);//Check callback. Key --> /content + @POST("/user/inventory/sell/{type}/{key}") void sellItem(@Path("type") String type, @Path("key") String key);//Check callback diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentGear.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentGear.java new file mode 100644 index 000000000..2d53d6b65 --- /dev/null +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentGear.java @@ -0,0 +1,11 @@ +package com.magicmicky.habitrpgwrapper.lib.models; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; + +import java.util.HashMap; + +public class ContentGear{ + + public HashMap flat; + +} diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentResult.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentResult.java new file mode 100644 index 000000000..5238ff366 --- /dev/null +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/ContentResult.java @@ -0,0 +1,16 @@ +package com.magicmicky.habitrpgwrapper.lib.models; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; + +/** + * Created by Negue on 15.07.2015. + */ +public class ContentResult { + + public ItemData potion; + + public ItemData armoire; + + public ContentGear gear; +} + diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/ItemData.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/ItemData.java new file mode 100644 index 000000000..5159b1502 --- /dev/null +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/ItemData.java @@ -0,0 +1,45 @@ +package com.magicmicky.habitrpgwrapper.lib.models.tasks; + +import com.google.gson.annotations.SerializedName; +import com.habitrpg.android.habitica.HabitDatabase; +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; +import com.raizlabs.android.dbflow.structure.BaseModel; + +/** + * Created by Negue on 13.07.2015. + */ +@Table(databaseName = HabitDatabase.NAME) +public class ItemData extends BaseModel { + public ItemData(){} + + @Column + public double value; + + @Column + public String type; + + @PrimaryKey + @Column + public String key; + + @Column + public String klass; + + @Column(name = "_index") + public String index; + + @Column + public String text; + + @Column + public String notes; + + @Column + public float con, str, per; + + @Column + @SerializedName("int") + public float _int; +} diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/RewardItem.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/RewardItem.java new file mode 100644 index 000000000..a3f030cf8 --- /dev/null +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/tasks/RewardItem.java @@ -0,0 +1,8 @@ +package com.magicmicky.habitrpgwrapper.lib.models.tasks; + +/** + * Created by Negue on 15.07.2015. + */ +public class RewardItem extends Reward { + +}