From aa79010ea0e9e8b50b1c20e02ec6b92c742837b9 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 19 Nov 2015 16:50:03 +0100 Subject: [PATCH] begin reworking activities into fragments --- Habitica/AndroidManifest.xml | 16 +- Habitica/res/layout/activity_main.xml | 110 +-- Habitica/res/layout/activity_tasks.xml | 171 ++++ Habitica/res/layout/fragment_party.xml | 5 + Habitica/res/layout/fragment_tasks.xml | 5 + Habitica/res/menu/menu_main_activity.xml | 2 +- .../android/habitica/AvatarActivityBase.java | 3 +- .../android/habitica/BaseFragment.java | 31 + .../android/habitica/GemPurchaseActivity.java | 3 - .../android/habitica/LoginActivity.java | 15 +- .../android/habitica/MainActivity.java | 835 +++--------------- .../android/habitica/PartyFragment.java | 160 ++++ .../android/habitica/TaskActivity.java | 783 ++++++++++++++++ .../android/habitica/TasksFragment.java | 209 +++++ .../android/habitica/TavernActivity.java | 4 +- .../habitica/ui/MainDrawerBuilder.java | 45 +- .../habitica/widget/UpdateWidgetService.java | 6 +- .../habitrpgwrapper/lib/api/ApiService.java | 2 +- 18 files changed, 1551 insertions(+), 854 deletions(-) create mode 100644 Habitica/res/layout/activity_tasks.xml create mode 100644 Habitica/res/layout/fragment_party.xml create mode 100644 Habitica/res/layout/fragment_tasks.xml create mode 100644 Habitica/src/com/habitrpg/android/habitica/BaseFragment.java create mode 100644 Habitica/src/com/habitrpg/android/habitica/PartyFragment.java create mode 100644 Habitica/src/com/habitrpg/android/habitica/TaskActivity.java create mode 100644 Habitica/src/com/habitrpg/android/habitica/TasksFragment.java diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index a78699f3b..da9a7e972 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -81,34 +81,34 @@ + android:parentActivityName=".TaskActivity"> + android:value=".TaskActivity" /> + android:parentActivityName=".TaskActivity"> + android:value=".TaskActivity" /> + android:parentActivityName=".TaskActivity"> + android:value=".TaskActivity" /> + android:parentActivityName=".TaskActivity"> + android:value=".TaskActivity" /> + tools:context=".PartyActivity"> - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Habitica/res/layout/activity_tasks.xml b/Habitica/res/layout/activity_tasks.xml new file mode 100644 index 000000000..b8fb3b740 --- /dev/null +++ b/Habitica/res/layout/activity_tasks.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fragment_party.xml b/Habitica/res/layout/fragment_party.xml new file mode 100644 index 000000000..8f05336f1 --- /dev/null +++ b/Habitica/res/layout/fragment_party.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/Habitica/res/layout/fragment_tasks.xml b/Habitica/res/layout/fragment_tasks.xml new file mode 100644 index 000000000..8eb1f0a7d --- /dev/null +++ b/Habitica/res/layout/fragment_tasks.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/Habitica/res/menu/menu_main_activity.xml b/Habitica/res/menu/menu_main_activity.xml index ea0d0d171..b4078ec39 100644 --- a/Habitica/res/menu/menu_main_activity.xml +++ b/Habitica/res/menu/menu_main_activity.xml @@ -1,7 +1,7 @@ + tools:context="com.habitrpg.android.habitica.TaskActivity"> ViewFragmentsDictionary = new HashMap<>(); + @InjectView(R.id.collapsing_toolbar) + CollapsingToolbarLayout collapsingToolbarLayout; - APIHelper mAPIHelper; + TextView titleTextView; - @InjectView(R.id.fab_menu) - FloatingActionMenu floatingMenu; + AccountHeader accountHeader; + Drawer drawer; + + protected HostConfig hostConfig; + protected HabitRPGUser user; + + AvatarWithBarsViewModel avatarInHeader; FlowContentObserver observer; - - private TagsHelper tagsHelper; - - private ContentCache contentCache; - - private MaterialDialog faintDialog; + APIHelper mAPIHelper; @Override - protected int getLayoutRes() { - return R.layout.activity_main; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // Inject Controls + ButterKnife.inject(this); + + // Initialize Crashlytics + Crashlytics crashlytics = new Crashlytics.Builder() + .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) + .build(); + Fabric.with(this, crashlytics); this.hostConfig = PrefsActivity.fromContext(this); if (hostConfig == null || hostConfig.getApi() == null || hostConfig.getApi().equals("") || hostConfig.getUser() == null || hostConfig.getUser().equals("")) { @@ -126,15 +91,7 @@ public class MainActivity extends AvatarActivityBase implements HabitRPGUserCall finish(); return; } - - - filterDrawer = new DrawerBuilder() - .withActivity(this) - .withDrawerGravity(Gravity.RIGHT) - .withCloseOnClick(false) - .append(drawer); - - viewPager.setCurrentItem(0); + this.mAPIHelper = new APIHelper(this, hostConfig); new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener); this.observer = new FlowContentObserver(); @@ -142,560 +99,61 @@ public class MainActivity extends AvatarActivityBase implements HabitRPGUserCall this.observer.addSpecificModelChangeListener(this); - this.tagsHelper = new TagsHelper(); + + if (toolbar != null) { + setSupportActionBar(toolbar); + + ActionBar actionBar = getSupportActionBar(); + + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(false); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setDisplayUseLogoEnabled(false); + actionBar.setHomeButtonEnabled(false); + } + + } + + avatarInHeader = new AvatarWithBarsViewModel(this, avatar_with_bars); + accountHeader = MainDrawerBuilder.CreateDefaultAccountHeader(this).build(); + drawer = MainDrawerBuilder.CreateDefaultBuilderSettings(this, toolbar, accountHeader) + .build(); + + // Create a new Fragment to be placed in the activity layout + TasksFragment tasksFragment = new TasksFragment(); + + // In case this activity was started with special instructions from an + // Intent, pass the Intent's extras to the fragment as arguments + this.displayFragment(tasksFragment); } @Override protected void onResume() { super.onResume(); - - if (mAPIHelper == null) { - this.mAPIHelper = new APIHelper(this, hostConfig); - - mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); - - contentCache = new ContentCache(mAPIHelper.apiService); - } + mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); SetUserData(); } - @Override - protected void onDestroy() { - if (observer != null) { - this.observer.unregisterForContentChanges(this.getApplicationContext()); - } - EventBus.getDefault().unregister(this); + public void displayFragment(BaseFragment fragment) { + fragment.setArguments(getIntent().getExtras()); + fragment.mAPIHelper = mAPIHelper; + fragment.setUser(user); + fragment.setActivity(this); + fragment.setTabLayout(detail_tabs); - super.onDestroy(); - } - - // region onClick for the FAB Menu - - @OnClick(R.id.fab_new_habit) - public void onNewHabit(View view) { - openNewTaskActivity("habit"); - } - - @OnClick(R.id.fab_new_daily) - public void onNewDaily(View view) { - openNewTaskActivity("daily"); - } - - @OnClick(R.id.fab_new_todo) - public void onNewTodo(View view) { - openNewTaskActivity("todo"); - } - - @OnClick(R.id.fab_new_reward) - public void onNewReward(View view) { - openNewTaskActivity("reward"); - } - - - private void openNewTaskActivity(String type) { - Bundle bundle = new Bundle(); - bundle.putString("type", type); - bundle.putStringArrayList("tagsId", new ArrayList(this.tagsHelper.getTags())); - - Intent intent = new Intent(this, TaskFormActivity.class); - intent.putExtras(bundle); - intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - - startActivityForResult(intent, TASK_CREATED_RESULT); - } - - // endregion - - private void showSnackbar(String content) { - showSnackbar(content, SnackbarDisplayType.NORMAL); - } - - private void showSnackbar(String content, SnackbarDisplayType displayType) { - Snackbar snackbar = Snackbar.make(floatingMenu, content, Snackbar.LENGTH_LONG); - View snackbarView = snackbar.getView(); - - if (displayType == SnackbarDisplayType.FAILURE) { - - //change Snackbar's background color; - snackbarView.setBackgroundColor(ContextCompat.getColor(this, R.color.worse_10)); - } else if (displayType == SnackbarDisplayType.DROP) { - TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text); - tv.setMaxLines(5); - snackbarView.setBackgroundColor(ContextCompat.getColor(this, R.color.best_10)); - } - snackbar.show(); - } - - //region Events - - public void onEvent(CreateTagCommand event) { - Tag t = new Tag(); - t.setName(event.tagName); - t.save(); - - mAPIHelper.apiService.createTag(t, new Callback>() { - @Override - public void success(List tags, Response response) { - FillTagFilterDrawer(tags); - } - - @Override - public void failure(RetrofitError error) { - showSnackbar("Error: " + error.getMessage(), SnackbarDisplayType.FAILURE); - } - }); - } - - public void onEvent(TaskTappedEvent event) { - if (event.Task.type.equals("reward")) - return; - - Bundle bundle = new Bundle(); - bundle.putString("type", event.Task.getType()); - bundle.putString("taskId", event.Task.getId()); - bundle.putStringArrayList("tagsId", new ArrayList(this.tagsHelper.getTags())); - Intent intent = new Intent(this, TaskFormActivity.class); - intent.putExtras(bundle); - startActivityForResult(intent, TASK_UPDATED_RESULT); - } - - public void onEvent(TaskLongPressedEvent event) { - } - - public void onEvent(TaskCheckedCommand event) { - mAPIHelper.updateTaskDirection(event.Task.getId(), event.Task.getCompleted() ? TaskDirection.down : TaskDirection.up, new TaskScoringCallback(this, event.Task.getId())); - } - - public void onEvent(HabitScoreEvent event) { - mAPIHelper.updateTaskDirection(event.Habit.getId(), event.Up ? TaskDirection.up : TaskDirection.down, new TaskScoringCallback(this, event.Habit.getId())); - } - - public void onEvent(AddNewTaskCommand event) { - openNewTaskActivity(event.ClassType.toLowerCase()); - } - - public void onEvent(final BuyRewardCommand event) { - final String rewardKey = event.Reward.getId(); - - if (User.getStats().getGp() < event.Reward.getValue()) { - showSnackbar("Not enough Gold", SnackbarDisplayType.FAILURE); - return; - } - - if (event.Reward.specialTag == "item") { - 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", SnackbarDisplayType.FAILURE); - 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; - default: - - // TODO Add bought item to the avatar - - break; - } - - showSnackbar("Buy Reward Successful " + event.Reward.getText()); - } - - @Override - public void failure(RetrofitError error) { - showSnackbar("Buy Reward Error " + event.Reward.getText(), SnackbarDisplayType.FAILURE); - } - }); + if (getSupportFragmentManager().getFragments() == null) { + getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, fragment).commit(); } else { - // User created Rewards - - mAPIHelper.updateTaskDirection(rewardKey, TaskDirection.down, new TaskScoringCallback(this, rewardKey)); - } - } - - public void onEvent(final TaskSaveEvent event) { - Task task = (Task) event.task; - Log.d("tags", "Task saving"); - if (event.created) { - this.mAPIHelper.createNewTask(task, new TaskCreationCallback()); - updateTags(event.task.getTags()); - } else { - this.mAPIHelper.updateTask(task, new TaskUpdateCallback()); - } - } - - public void onEvent(ToggledInnStateEvent event) { - User.getPreferences().setSleep(event.Inn); - - updateUserAvatars(); - } - - //endregion Events - - private void notifyUser(double xp, double hp, double gold, - int lvl, double delta) { - StringBuilder message = new StringBuilder(); - SnackbarDisplayType displayType = SnackbarDisplayType.NORMAL; - if (lvl > User.getStats().getLvl()) { - displayLevelUpDialog(lvl); - - this.mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); - User.getStats().setLvl((int) lvl); - showSnackbar(message.toString()); - } else { - com.magicmicky.habitrpgwrapper.lib.models.Stats stats = User.getStats(); - - if (xp > stats.getExp()) { - message.append(" + ").append(round(xp - stats.getExp(), 2)).append(" XP"); - User.getStats().setExp(xp); - } - if (hp != stats.getHp()) { - displayType = SnackbarDisplayType.FAILURE; - message.append(" - ").append(round(stats.getHp() - hp, 2)).append(" HP"); - User.getStats().setHp(hp); - } - if (gold > stats.getGp()) { - message.append(" + ").append(round(gold - stats.getGp(), 2)).append(" GP"); - stats.setGp(gold); - } else if (gold < stats.getGp()) { - displayType = SnackbarDisplayType.FAILURE; - message.append(" - ").append(round(stats.getGp() - gold, 2)).append(" GP"); - stats.setGp(gold); - } - showSnackbar(message.toString(), displayType); - - updateUserAvatars(); - } - } - - static public Double round(Double value, int n) { - return (Math.round(value * Math.pow(10, n))) / (Math.pow(10, n)); - } - - public void loadTaskLists() { - android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); - - viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { - - int oldPosition = -1; - - @Override - public Fragment getItem(int position) { - int layoutOfType; - TaskRecyclerViewFragment fragment; - HabitItemRecyclerViewAdapter adapter; - - switch (position) { - case 0: - layoutOfType = R.layout.habit_item_card; - fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_HABIT, MainActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.HabitViewHolder.class, MainActivity.this), Task.TYPE_HABIT); - - break; - case 1: - layoutOfType = R.layout.daily_item_card; - adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_DAILY, MainActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.DailyViewHolder.class, MainActivity.this); - if (User != null) { - adapter.dailyResetOffset = User.getPreferences().getDayStart(); - } - fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_DAILY); - break; - case 3: - layoutOfType = R.layout.reward_item_card; - adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_REWARD, MainActivity.this.tagsHelper, - layoutOfType, HabitItemRecyclerViewAdapter.RewardViewHolder.class, MainActivity.this, - new HabitItemRecyclerViewAdapter.IAdditionalEntries() { - @Override - public void GetAdditionalEntries(final IReceiveNewEntries callBack) { - - // request buyable gear - mAPIHelper.apiService.getInventoryBuyableGear(new Callback>() { - @Override - public void success(List itemDatas, Response response) { - - // get itemdata list - ArrayList itemKeys = new ArrayList(); - for (ItemData item : itemDatas) { - itemKeys.add(item.key); - } - itemKeys.add("potion"); - - contentCache.GetItemDataList(itemKeys, new ContentCache.GotContentEntryCallback>() { - @Override - public void GotObject(List obj) { - ArrayList buyableItems = new ArrayList(); - - for (ItemData item : obj) { - Task reward = new Task(); - reward.text = item.text; - reward.notes = item.notes; - reward.value = item.value; - reward.setType("reward"); - reward.specialTag = "item"; - reward.setId(item.key); - - buyableItems.add(reward); - } - - callBack.GotAdditionalItems(buyableItems); - - } - }); - - - } - - @Override - public void failure(RetrofitError error) { - - } - }); - - } - }); - - - fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_REWARD); - break; - default: - layoutOfType = R.layout.todo_item_card; - fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_TODO, MainActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.TodoViewHolder.class, MainActivity.this), Task.TYPE_TODO); - } - - ViewFragmentsDictionary.put(position, fragment); - - return fragment; - } - - @Override - public int getCount() { - return 4; - } - - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case 0: - return "Habits"; - case 1: - return "Dailies"; - case 2: - return "Todos"; - case 3: - return "Rewards"; - } - return ""; - } - }); - - - detail_tabs.setupWithViewPager(viewPager); - - } - - - public int adjustAlpha(int color, float factor) { - int alpha = Math.round(Color.alpha(color) * factor); - int red = Color.red(color); - int green = Color.green(color); - int blue = Color.blue(color); - return Color.argb(alpha, red, green, blue); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_main_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - switch (id) { - case R.id.action_search: - filterDrawer.openDrawer(); - return true; - case R.id.action_reload: - mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); - return true; - } - - return super.onOptionsItemSelected(item); - } - - private void updateUserAvatars() { - avatarInHeader.updateData(User); - } - - private void updateHeader() { - updateUserAvatars(); - setTitle(User.getProfile().getName()); - - android.support.v7.app.ActionBarDrawerToggle actionBarDrawerToggle = drawer.getActionBarDrawerToggle(); - - if (actionBarDrawerToggle != null) { - actionBarDrawerToggle.setDrawerIndicatorEnabled(true); - } - } - - @Override - public void onUserReceived(HabitRPGUser user) { - } - - @Override - public void onUserFail() { - - } - - @Override - public void onTaskDataReceived(TaskDirectionData data) { - notifyUser(data.getExp(), data.getHp(), data.getGp(), data.getLvl(), data.getDelta()); - if (data.get_tmp() != null) { - if (data.get_tmp().getDrop() != null) { - showSnackbar(data.get_tmp().getDrop().getDialog(), SnackbarDisplayType.DROP); - } - } - - } - - @Override - public void onTaskScoringFailed() { - - } - - @Override - public void onModelStateChanged(Class aClass, BaseModel.Action action, String s, String s1) { - if (aClass != HabitRPGUser.class) - return; - - - new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener); - Log.d("db", "received notif"); -// SetUserData(); - } - - private boolean taskListAlreadyAdded; - - private void SetUserData() { - if (User != null) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (!taskListAlreadyAdded) { - taskListAlreadyAdded = true; - loadTaskLists(); - FillTagFilterDrawer(User.getTags()); - } - TaskRecyclerViewFragment fragment = ViewFragmentsDictionary.get(2); - if (fragment != null) { - HabitItemRecyclerViewAdapter adapter =(HabitItemRecyclerViewAdapter)fragment.mAdapter; - adapter.dailyResetOffset = User.getPreferences().getDayStart(); - } - updateHeader(); - updateSidebar(); - displayDeathDialogIfNeeded(); - } - }); - } - } - - // Filter Tags - - public void FillTagFilterDrawer(List tagList) { - filterDrawer.removeAllItems(); - filterDrawer.addItems( - new SectionDrawerItem().withName("Filter by Tag"), - new EditTextDrawer() - ); - - for (Tag t : tagList) { - filterDrawer.addItem(new SwitchDrawerItem() - .withName(t.getName()) - .withTag(t) - .withDescription("" + t.getTasks().size()) - .withOnCheckedChangeListener(this) - ); - } - } - - /* - Updates concerned tags. - */ - public void updateTags(List tags) { - Log.d("tags", "Updating tags"); - List filters = filterDrawer.getDrawerItems(); - for (IDrawerItem filter : filters) { - if (filter instanceof SwitchDrawerItem) { - SwitchDrawerItem currentfilter = (SwitchDrawerItem) filter; - Log.v("tags", "Tag " + currentfilter.getName()); - String tagId = ((Tag) currentfilter.getTag()).getId(); - for (TaskTag tag : tags) { - Tag currentTag = tag.getTag(); - - - if (tagId != null && currentTag != null && tagId.equals(currentTag.getId())) { - currentfilter.withDescription("" + (currentTag.getTasks().size() + 1)); - filterDrawer.updateItem(currentfilter); - } - } - } - } - - } - - // A Filter was checked - - private Debounce filterChangedHandler = new Debounce(1500, 1000) { - @Override - public void execute() { - ArrayList tagList = new ArrayList<>(); - - for (Map.Entry f : tagFilterMap.entrySet()) { - if (f.getValue()) { - tagList.add(f.getKey()); - } - } - tagsHelper.setTags(tagList); - EventBus.getDefault().post(new FilterTasksByTagsCommand()); - } - }; - - - private HashMap tagFilterMap = new HashMap<>(); - - @Override - public void onCheckedChanged(IDrawerItem iDrawerItem, CompoundButton compoundButton, boolean b) { - Tag t = (Tag) iDrawerItem.getTag(); - Log.w("Tags", "onCheckedChanged" + compoundButton.isChecked() + " : " + b); - if (t != null) { - tagFilterMap.put(t.getId(), b); - filterChangedHandler.hit(); - showSnackbar(t.getName() + " : " + b); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).addToBackStack(null).commit(); } + activeFragment = fragment; } private TransactionListener userTransactionListener = new TransactionListener() { @Override public void onResultReceived(HabitRPGUser habitRPGUser) { - User = habitRPGUser; + user = habitRPGUser; SetUserData(); } @@ -710,77 +168,68 @@ public class MainActivity extends AvatarActivityBase implements HabitRPGUserCall } }; - private void displayLevelUpDialog(int level) { - SuppressedModals suppressedModals = User.getPreferences().getSuppressModals(); - if (suppressedModals != null) { - if (suppressedModals.getLevelUp()) { - return; - } - } - - MaterialDialog dialog = new MaterialDialog.Builder(this) - .title(R.string.levelup_header) - .customView(R.layout.levelup_dialog, true) - .positiveText(R.string.levelup_button) - .positiveColorRes(R.color.brand_100) - .build(); - - View customView = dialog.getCustomView(); - if (customView != null) { - TextView detailView = (TextView)customView.findViewById(R.id.levelupDetail); - detailView.setText(this.getString(R.string.levelup_detail, level)); - - ImageView avatarView = (ImageView)customView.findViewById(R.id.avatarView); - UserPicture userPicture = new UserPicture(User, this, false, false); - userPicture.setPictureOn(avatarView); - } - - dialog.show(); - } - - private void displayDeathDialogIfNeeded() { - - if (User.getStats().getHp() > 0) { + @Override + public void onModelStateChanged(Class aClass, BaseModel.Action action, String s, String s1) { + if (aClass != HabitRPGUser.class) return; + + + new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener); + } + + private void SetUserData() { + if (user != null) { + runOnUiThread(new Runnable() { + @Override + public void run() { + updateHeader(); + updateSidebar(); + if (activeFragment != null) { + activeFragment.updateUserData(user); + } + } + }); } + } - if (this.faintDialog == null) { - final MainActivity activity = this; - this.faintDialog = new MaterialDialog.Builder(this) - .title(R.string.faint_header) - .customView(R.layout.faint_dialog, true) - .positiveText(R.string.faint_button) - .positiveColorRes(R.color.worse_100) - .dismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - faintDialog = null; - mAPIHelper.reviveUser(new HabitRPGUserCallback(activity)); - } - }) - .cancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - faintDialog = null; - } - }) - .build(); + private void updateUserAvatars() { + avatarInHeader.updateData(user); + } - View customView = this.faintDialog.getCustomView(); - if (customView != null) { - View hpBarView = customView.findViewById(R.id.hpBar); + private void updateHeader() { + updateUserAvatars(); + setTitle(user.getProfile().getName()); - ValueBarBinding hpBar = DataBindingUtil.bind(hpBarView); - hpBar.setPartyMembers(true); - AvatarWithBarsViewModel.setHpBarData(hpBar, User.getStats(), this); + android.support.v7.app.ActionBarDrawerToggle actionBarDrawerToggle = drawer.getActionBarDrawerToggle(); - ImageView avatarView = (ImageView)customView.findViewById(R.id.avatarView); - UserPicture userPicture = new UserPicture(User, this, false, false); - userPicture.setPictureOn(avatarView); + if (actionBarDrawerToggle != null) { + actionBarDrawerToggle.setDrawerIndicatorEnabled(true); + } + } + + public void updateSidebar() { + final IProfile profile = accountHeader.getProfiles().get(0); + if (user.getAuthentication() != null) { + if (user.getAuthentication().getLocalAuthentication() != null) { + profile.withEmail(user.getAuthentication().getLocalAuthentication().getEmail()); } - - this.faintDialog.show(); } + profile.withName(user.getProfile().getName()); + new UserPicture(user, this, true, false).setPictureWithRunnable(new UserPictureRunnable() { + public void run(Bitmap avatar) { + profile.withIcon(avatar); + accountHeader.updateProfile(profile); + } + }); + accountHeader.updateProfile(profile); + } + + @Override + public void onUserReceived(HabitRPGUser user) { + } + + @Override + public void onUserFail() { } -} \ No newline at end of file +} diff --git a/Habitica/src/com/habitrpg/android/habitica/PartyFragment.java b/Habitica/src/com/habitrpg/android/habitica/PartyFragment.java new file mode 100644 index 000000000..c7b1488ad --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/PartyFragment.java @@ -0,0 +1,160 @@ +package com.habitrpg.android.habitica; + +import android.os.Bundle; +import android.support.design.widget.AppBarLayout; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.habitrpg.android.habitica.events.commands.CreateTagCommand; +import com.habitrpg.android.habitica.helpers.TagsHelper; +import com.habitrpg.android.habitica.ui.fragments.ChatListFragment; +import com.habitrpg.android.habitica.ui.fragments.PartyInformationFragment; +import com.habitrpg.android.habitica.ui.fragments.PartyMemberListFragment; +import com.magicmicky.habitrpgwrapper.lib.models.Group; +import com.magicmicky.habitrpgwrapper.lib.models.QuestContent; +import com.mikepenz.materialdrawer.DrawerBuilder; + +import java.util.HashMap; + +import retrofit.Callback; +import retrofit.RetrofitError; +import retrofit.client.Response; + +/** + * Created by admin on 18/11/15. + */ +public class PartyFragment extends BaseFragment { + + public TabLayout tabLayout; + public ViewPager viewPager; + private Group group; + private HashMap fragmentDictionary = new HashMap<>(); + + private PartyMemberListFragment partyMemberListFragment; + private PartyInformationFragment partyInformationFragment; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View v = inflater.inflate(R.layout.fragment_party, container, false); + + viewPager = (ViewPager) v.findViewById(R.id.view_pager); + + viewPager.setCurrentItem(0); + + final ContentCache contentCache = new ContentCache(mAPIHelper.apiService); + + + // Get the full group data + mAPIHelper.apiService.getGroup("party", new Callback() { + @Override + public void success(Group group, Response response) { + PartyFragment.this.group = group; + + if (partyMemberListFragment != null) { + partyMemberListFragment.setMemberList(group.members); + } + + if (partyInformationFragment != null) { + partyInformationFragment.setGroup(group); + } + + if (group != null && group.quest != null && !group.quest.key.isEmpty()) { + contentCache.GetQuestContent(group.quest.key, new ContentCache.QuestContentCallback() { + @Override + public void GotQuest(QuestContent content) { + if (partyInformationFragment != null) { + partyInformationFragment.setQuestContent(content); + } + } + }); + } + } + + @Override + public void failure(RetrofitError error) { + + } + }); + setViewPagerAdapter(); + + return v; + } + + @Override + public void setTabLayout(TabLayout tabLayout) { + this.tabLayout = tabLayout; + this.tabLayout.removeAllTabs(); + } + + public void setViewPagerAdapter() { + android.support.v4.app.FragmentManager fragmentManager = getChildFragmentManager(); + + viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { + + @Override + public Fragment getItem(int position) { + + Fragment fragment; + + switch (position) { + case 0: { + fragment = partyInformationFragment = new PartyInformationFragment(group); + break; + } + case 1: { + fragment = new ChatListFragment(activity, "party", mAPIHelper, user, false); + break; + } + case 2: { + fragment = partyMemberListFragment = new PartyMemberListFragment(activity, group); + break; + } + default: + fragment = new Fragment(); + } + + fragmentDictionary.put(position, fragment); + + return fragment; + } + + @Override + public int getCount() { + return 3; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "Party"; + case 1: + return "Chat"; + case 2: + return "Members"; + } + return ""; + } + }); + + + tabLayout.setupWithViewPager(viewPager); + } + + + //region Events + + // until there is a party event + public void onEvent(CreateTagCommand event) { + + } + +} diff --git a/Habitica/src/com/habitrpg/android/habitica/TaskActivity.java b/Habitica/src/com/habitrpg/android/habitica/TaskActivity.java new file mode 100644 index 000000000..5030d4631 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/TaskActivity.java @@ -0,0 +1,783 @@ +package com.habitrpg.android.habitica; + +import android.content.DialogInterface; +import android.content.Intent; +import android.databinding.DataBindingUtil; +import android.graphics.Color; +import android.os.Bundle; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.content.ContextCompat; +import android.util.Log; +import android.view.Gravity; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.TextView; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.github.clans.fab.FloatingActionMenu; +import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback; +import com.habitrpg.android.habitica.callbacks.TaskCreationCallback; +import com.habitrpg.android.habitica.callbacks.TaskScoringCallback; +import com.habitrpg.android.habitica.callbacks.TaskUpdateCallback; +import com.habitrpg.android.habitica.databinding.ValueBarBinding; +import com.habitrpg.android.habitica.events.commands.BuyRewardCommand; +import com.habitrpg.android.habitica.events.HabitScoreEvent; +import com.habitrpg.android.habitica.events.commands.TaskCheckedCommand; +import com.habitrpg.android.habitica.events.TaskLongPressedEvent; +import com.habitrpg.android.habitica.events.TaskSaveEvent; +import com.habitrpg.android.habitica.events.TaskTappedEvent; +import com.habitrpg.android.habitica.events.ToggledInnStateEvent; +import com.habitrpg.android.habitica.events.commands.AddNewTaskCommand; +import com.habitrpg.android.habitica.events.commands.CreateTagCommand; +import com.habitrpg.android.habitica.events.commands.FilterTasksByTagsCommand; +import com.habitrpg.android.habitica.helpers.TagsHelper; +import com.habitrpg.android.habitica.prefs.PrefsActivity; +import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; +import com.habitrpg.android.habitica.ui.EditTextDrawer; +import com.habitrpg.android.habitica.ui.adapter.HabitItemRecyclerViewAdapter; +import com.habitrpg.android.habitica.ui.adapter.IReceiveNewEntries; +import com.habitrpg.android.habitica.ui.fragments.TaskRecyclerViewFragment; +import com.habitrpg.android.habitica.ui.helpers.Debounce; +import com.habitrpg.android.habitica.userpicture.UserPicture; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.SuppressedModals; +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.tasks.ItemData; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.TaskTag; +import com.mikepenz.materialdrawer.Drawer; +import com.mikepenz.materialdrawer.DrawerBuilder; +import com.mikepenz.materialdrawer.model.SectionDrawerItem; +import com.mikepenz.materialdrawer.model.SwitchDrawerItem; +import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; +import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener; +import com.raizlabs.android.dbflow.runtime.FlowContentObserver; +import com.raizlabs.android.dbflow.runtime.transaction.BaseTransaction; +import com.raizlabs.android.dbflow.runtime.transaction.TransactionListener; +import com.raizlabs.android.dbflow.sql.builder.Condition; +import com.raizlabs.android.dbflow.sql.language.Select; +import com.raizlabs.android.dbflow.structure.BaseModel; +import com.raizlabs.android.dbflow.structure.Model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import butterknife.InjectView; +import butterknife.OnClick; +import de.greenrobot.event.EventBus; +import retrofit.Callback; +import retrofit.RetrofitError; +import retrofit.client.Response; + + + +public class TaskActivity extends AvatarActivityBase implements HabitRPGUserCallback.OnUserReceived, + TaskScoringCallback.OnTaskScored, FlowContentObserver.OnSpecificModelStateChangedListener, + OnCheckedChangeListener { + + public enum SnackbarDisplayType { + NORMAL, FAILURE, DROP + } + + static final int TASK_CREATED_RESULT = 1; + static final int TASK_UPDATED_RESULT = 2; + + Drawer filterDrawer; + + Map ViewFragmentsDictionary = new HashMap<>(); + + APIHelper mAPIHelper; + + @InjectView(R.id.fab_menu) + FloatingActionMenu floatingMenu; + + FlowContentObserver observer; + + private TagsHelper tagsHelper; + + private ContentCache contentCache; + + private MaterialDialog faintDialog; + + @Override + protected int getLayoutRes() { + return R.layout.activity_tasks; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + this.hostConfig = PrefsActivity.fromContext(this); + if (hostConfig == null || hostConfig.getApi() == null || hostConfig.getApi().equals("") || hostConfig.getUser() == null || hostConfig.getUser().equals("")) { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + return; + } + + + filterDrawer = new DrawerBuilder() + .withActivity(this) + .withDrawerGravity(Gravity.RIGHT) + .withCloseOnClick(false) + .append(drawer); + + viewPager.setCurrentItem(0); + + new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener); + this.observer = new FlowContentObserver(); + this.observer.registerForContentChanges(this.getApplicationContext(), HabitRPGUser.class); + + this.observer.addSpecificModelChangeListener(this); + + this.tagsHelper = new TagsHelper(); + } + + @Override + protected void onResume() { + super.onResume(); + + if (mAPIHelper == null) { + this.mAPIHelper = new APIHelper(this, hostConfig); + + mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); + + contentCache = new ContentCache(mAPIHelper.apiService); + } + SetUserData(); + } + + @Override + protected void onDestroy() { + if (observer != null) { + this.observer.unregisterForContentChanges(this.getApplicationContext()); + } + EventBus.getDefault().unregister(this); + + super.onDestroy(); + } + + // region onClick for the FAB Menu + + @OnClick(R.id.fab_new_habit) + public void onNewHabit(View view) { + openNewTaskActivity("habit"); + } + + @OnClick(R.id.fab_new_daily) + public void onNewDaily(View view) { + openNewTaskActivity("daily"); + } + + @OnClick(R.id.fab_new_todo) + public void onNewTodo(View view) { + openNewTaskActivity("todo"); + } + + @OnClick(R.id.fab_new_reward) + public void onNewReward(View view) { + openNewTaskActivity("reward"); + } + + + private void openNewTaskActivity(String type) { + Bundle bundle = new Bundle(); + bundle.putString("type", type); + bundle.putStringArrayList("tagsId", new ArrayList(this.tagsHelper.getTags())); + + Intent intent = new Intent(this, TaskFormActivity.class); + intent.putExtras(bundle); + intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + + startActivityForResult(intent, TASK_CREATED_RESULT); + } + + // endregion + + private void showSnackbar(String content) { + showSnackbar(content, SnackbarDisplayType.NORMAL); + } + + private void showSnackbar(String content, SnackbarDisplayType displayType) { + Snackbar snackbar = Snackbar.make(floatingMenu, content, Snackbar.LENGTH_LONG); + View snackbarView = snackbar.getView(); + + if (displayType == SnackbarDisplayType.FAILURE) { + + //change Snackbar's background color; + snackbarView.setBackgroundColor(ContextCompat.getColor(this, R.color.worse_10)); + } else if (displayType == SnackbarDisplayType.DROP) { + TextView tv = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text); + tv.setMaxLines(5); + snackbarView.setBackgroundColor(ContextCompat.getColor(this, R.color.best_10)); + } + snackbar.show(); + } + + //region Events + + public void onEvent(CreateTagCommand event) { + Tag t = new Tag(); + t.setName(event.tagName); + t.save(); + + mAPIHelper.apiService.createTag(t, new Callback>() { + @Override + public void success(List tags, Response response) { + FillTagFilterDrawer(tags); + } + + @Override + public void failure(RetrofitError error) { + showSnackbar("Error: " + error.getMessage(), SnackbarDisplayType.FAILURE); + } + }); + } + + public void onEvent(TaskTappedEvent event) { + if (event.Task.type.equals("reward")) + return; + + Bundle bundle = new Bundle(); + bundle.putString("type", event.Task.getType()); + bundle.putString("taskId", event.Task.getId()); + bundle.putStringArrayList("tagsId", new ArrayList(this.tagsHelper.getTags())); + Intent intent = new Intent(this, TaskFormActivity.class); + intent.putExtras(bundle); + startActivityForResult(intent, TASK_UPDATED_RESULT); + } + + public void onEvent(TaskLongPressedEvent event) { + } + + public void onEvent(TaskCheckedCommand event) { + mAPIHelper.updateTaskDirection(event.Task.getId(), event.Task.getCompleted() ? TaskDirection.down : TaskDirection.up, new TaskScoringCallback(this, event.Task.getId())); + } + + public void onEvent(HabitScoreEvent event) { + mAPIHelper.updateTaskDirection(event.Habit.getId(), event.Up ? TaskDirection.up : TaskDirection.down, new TaskScoringCallback(this, event.Habit.getId())); + } + + public void onEvent(AddNewTaskCommand event) { + openNewTaskActivity(event.ClassType.toLowerCase()); + } + + public void onEvent(final BuyRewardCommand event) { + final String rewardKey = event.Reward.getId(); + + if (User.getStats().getGp() < event.Reward.getValue()) { + showSnackbar("Not enough Gold", SnackbarDisplayType.FAILURE); + return; + } + + if (event.Reward.specialTag == "item") { + 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", SnackbarDisplayType.FAILURE); + 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; + default: + + // TODO Add bought item to the avatar + + break; + } + + showSnackbar("Buy Reward Successful " + event.Reward.getText()); + } + + @Override + public void failure(RetrofitError error) { + showSnackbar("Buy Reward Error " + event.Reward.getText(), SnackbarDisplayType.FAILURE); + } + }); + } else { + // user created Rewards + + mAPIHelper.updateTaskDirection(rewardKey, TaskDirection.down, new TaskScoringCallback(this, rewardKey)); + } + } + + public void onEvent(final TaskSaveEvent event) { + Task task = (Task) event.task; + Log.d("tags", "Task saving"); + if (event.created) { + this.mAPIHelper.createNewTask(task, new TaskCreationCallback()); + updateTags(event.task.getTags()); + } else { + this.mAPIHelper.updateTask(task, new TaskUpdateCallback()); + } + } + + public void onEvent(ToggledInnStateEvent event) { + User.getPreferences().setSleep(event.Inn); + + updateUserAvatars(); + } + + //endregion Events + + private void notifyUser(double xp, double hp, double gold, + int lvl, double delta) { + StringBuilder message = new StringBuilder(); + SnackbarDisplayType displayType = SnackbarDisplayType.NORMAL; + if (lvl > User.getStats().getLvl()) { + displayLevelUpDialog(lvl); + + this.mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); + User.getStats().setLvl((int) lvl); + showSnackbar(message.toString()); + } else { + com.magicmicky.habitrpgwrapper.lib.models.Stats stats = User.getStats(); + + if (xp > stats.getExp()) { + message.append(" + ").append(round(xp - stats.getExp(), 2)).append(" XP"); + User.getStats().setExp(xp); + } + if (hp != stats.getHp()) { + displayType = SnackbarDisplayType.FAILURE; + message.append(" - ").append(round(stats.getHp() - hp, 2)).append(" HP"); + User.getStats().setHp(hp); + } + if (gold > stats.getGp()) { + message.append(" + ").append(round(gold - stats.getGp(), 2)).append(" GP"); + stats.setGp(gold); + } else if (gold < stats.getGp()) { + displayType = SnackbarDisplayType.FAILURE; + message.append(" - ").append(round(stats.getGp() - gold, 2)).append(" GP"); + stats.setGp(gold); + } + showSnackbar(message.toString(), displayType); + + updateUserAvatars(); + } + } + + static public Double round(Double value, int n) { + return (Math.round(value * Math.pow(10, n))) / (Math.pow(10, n)); + } + + public void loadTaskLists() { + android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); + + viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { + + int oldPosition = -1; + + @Override + public Fragment getItem(int position) { + int layoutOfType; + TaskRecyclerViewFragment fragment; + HabitItemRecyclerViewAdapter adapter; + + switch (position) { + case 0: + layoutOfType = R.layout.habit_item_card; + fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_HABIT, TaskActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.HabitViewHolder.class, TaskActivity.this), Task.TYPE_HABIT); + + break; + case 1: + layoutOfType = R.layout.daily_item_card; + adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_DAILY, TaskActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.DailyViewHolder.class, TaskActivity.this); + if (User != null) { + adapter.dailyResetOffset = User.getPreferences().getDayStart(); + } + fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_DAILY); + break; + case 3: + layoutOfType = R.layout.reward_item_card; + adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_REWARD, TaskActivity.this.tagsHelper, + layoutOfType, HabitItemRecyclerViewAdapter.RewardViewHolder.class, TaskActivity.this, + new HabitItemRecyclerViewAdapter.IAdditionalEntries() { + @Override + public void GetAdditionalEntries(final IReceiveNewEntries callBack) { + + // request buyable gear + mAPIHelper.apiService.getInventoryBuyableGear(new Callback>() { + @Override + public void success(List itemDatas, Response response) { + + // get itemdata list + ArrayList itemKeys = new ArrayList(); + for (ItemData item : itemDatas) { + itemKeys.add(item.key); + } + itemKeys.add("potion"); + + contentCache.GetItemDataList(itemKeys, new ContentCache.GotContentEntryCallback>() { + @Override + public void GotObject(List obj) { + ArrayList buyableItems = new ArrayList(); + + for (ItemData item : obj) { + Task reward = new Task(); + reward.text = item.text; + reward.notes = item.notes; + reward.value = item.value; + reward.setType("reward"); + reward.specialTag = "item"; + reward.setId(item.key); + + buyableItems.add(reward); + } + + callBack.GotAdditionalItems(buyableItems); + + } + }); + + + } + + @Override + public void failure(RetrofitError error) { + + } + }); + + } + }); + + + fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_REWARD); + break; + default: + layoutOfType = R.layout.todo_item_card; + fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_TODO, TaskActivity.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.TodoViewHolder.class, TaskActivity.this), Task.TYPE_TODO); + } + + ViewFragmentsDictionary.put(position, fragment); + + return fragment; + } + + @Override + public int getCount() { + return 4; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "Habits"; + case 1: + return "Dailies"; + case 2: + return "Todos"; + case 3: + return "Rewards"; + } + return ""; + } + }); + + + detail_tabs.setupWithViewPager(viewPager); + + } + + + public int adjustAlpha(int color, float factor) { + int alpha = Math.round(Color.alpha(color) * factor); + int red = Color.red(color); + int green = Color.green(color); + int blue = Color.blue(color); + return Color.argb(alpha, red, green, blue); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + switch (id) { + case R.id.action_search: + filterDrawer.openDrawer(); + return true; + case R.id.action_reload: + mAPIHelper.retrieveUser(new HabitRPGUserCallback(this)); + return true; + } + + return super.onOptionsItemSelected(item); + } + + private void updateUserAvatars() { + avatarInHeader.updateData(User); + } + + private void updateHeader() { + updateUserAvatars(); + setTitle(User.getProfile().getName()); + + android.support.v7.app.ActionBarDrawerToggle actionBarDrawerToggle = drawer.getActionBarDrawerToggle(); + + if (actionBarDrawerToggle != null) { + actionBarDrawerToggle.setDrawerIndicatorEnabled(true); + } + } + + @Override + public void onUserReceived(HabitRPGUser user) { + } + + @Override + public void onUserFail() { + + } + + @Override + public void onTaskDataReceived(TaskDirectionData data) { + notifyUser(data.getExp(), data.getHp(), data.getGp(), data.getLvl(), data.getDelta()); + if (data.get_tmp() != null) { + if (data.get_tmp().getDrop() != null) { + showSnackbar(data.get_tmp().getDrop().getDialog(), SnackbarDisplayType.DROP); + } + } + + } + + @Override + public void onTaskScoringFailed() { + + } + + @Override + public void onModelStateChanged(Class aClass, BaseModel.Action action, String s, String s1) { + if (aClass != HabitRPGUser.class) + return; + + + new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener); + Log.d("db", "received notif"); +// SetUserData(); + } + + private boolean taskListAlreadyAdded; + + private void SetUserData() { + if (User != null) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (!taskListAlreadyAdded) { + taskListAlreadyAdded = true; + loadTaskLists(); + FillTagFilterDrawer(User.getTags()); + } + TaskRecyclerViewFragment fragment = ViewFragmentsDictionary.get(2); + if (fragment != null) { + HabitItemRecyclerViewAdapter adapter =(HabitItemRecyclerViewAdapter)fragment.mAdapter; + adapter.dailyResetOffset = User.getPreferences().getDayStart(); + } + updateHeader(); + updateSidebar(); + displayDeathDialogIfNeeded(); + } + }); + } + } + + // Filter Tags + + public void FillTagFilterDrawer(List tagList) { + filterDrawer.removeAllItems(); + filterDrawer.addItems( + new SectionDrawerItem().withName("Filter by Tag"), + new EditTextDrawer() + ); + + for (Tag t : tagList) { + filterDrawer.addItem(new SwitchDrawerItem() + .withName(t.getName()) + .withTag(t) + .withDescription("" + t.getTasks().size()) + .withOnCheckedChangeListener(this) + ); + } + } + + /* + Updates concerned tags. + */ + public void updateTags(List tags) { + Log.d("tags", "Updating tags"); + List filters = filterDrawer.getDrawerItems(); + for (IDrawerItem filter : filters) { + if (filter instanceof SwitchDrawerItem) { + SwitchDrawerItem currentfilter = (SwitchDrawerItem) filter; + Log.v("tags", "Tag " + currentfilter.getName()); + String tagId = ((Tag) currentfilter.getTag()).getId(); + for (TaskTag tag : tags) { + Tag currentTag = tag.getTag(); + + + if (tagId != null && currentTag != null && tagId.equals(currentTag.getId())) { + currentfilter.withDescription("" + (currentTag.getTasks().size() + 1)); + filterDrawer.updateItem(currentfilter); + } + } + } + } + + } + + // A Filter was checked + + private Debounce filterChangedHandler = new Debounce(1500, 1000) { + @Override + public void execute() { + ArrayList tagList = new ArrayList<>(); + + for (Map.Entry f : tagFilterMap.entrySet()) { + if (f.getValue()) { + tagList.add(f.getKey()); + } + } + tagsHelper.setTags(tagList); + EventBus.getDefault().post(new FilterTasksByTagsCommand()); + } + }; + + + private HashMap tagFilterMap = new HashMap<>(); + + @Override + public void onCheckedChanged(IDrawerItem iDrawerItem, CompoundButton compoundButton, boolean b) { + Tag t = (Tag) iDrawerItem.getTag(); + Log.w("Tags", "onCheckedChanged" + compoundButton.isChecked() + " : " + b); + if (t != null) { + tagFilterMap.put(t.getId(), b); + filterChangedHandler.hit(); + showSnackbar(t.getName() + " : " + b); + } + } + + private TransactionListener userTransactionListener = new TransactionListener() { + @Override + public void onResultReceived(HabitRPGUser habitRPGUser) { + User = habitRPGUser; + SetUserData(); + } + + @Override + public boolean onReady(BaseTransaction baseTransaction) { + return true; + } + + @Override + public boolean hasResult(BaseTransaction baseTransaction, HabitRPGUser habitRPGUser) { + return true; + } + }; + + private void displayLevelUpDialog(int level) { + SuppressedModals suppressedModals = User.getPreferences().getSuppressModals(); + if (suppressedModals != null) { + if (suppressedModals.getLevelUp()) { + return; + } + } + + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.levelup_header) + .customView(R.layout.levelup_dialog, true) + .positiveText(R.string.levelup_button) + .positiveColorRes(R.color.brand_100) + .build(); + + View customView = dialog.getCustomView(); + if (customView != null) { + TextView detailView = (TextView)customView.findViewById(R.id.levelupDetail); + detailView.setText(this.getString(R.string.levelup_detail, level)); + + ImageView avatarView = (ImageView)customView.findViewById(R.id.avatarView); + UserPicture userPicture = new UserPicture(User, this, false, false); + userPicture.setPictureOn(avatarView); + } + + dialog.show(); + } + + private void displayDeathDialogIfNeeded() { + + if (User.getStats().getHp() > 0) { + return; + } + + if (this.faintDialog == null) { + final TaskActivity activity = this; + this.faintDialog = new MaterialDialog.Builder(this) + .title(R.string.faint_header) + .customView(R.layout.faint_dialog, true) + .positiveText(R.string.faint_button) + .positiveColorRes(R.color.worse_100) + .dismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + faintDialog = null; + mAPIHelper.reviveUser(new HabitRPGUserCallback(activity)); + } + }) + .cancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + faintDialog = null; + } + }) + .build(); + + View customView = this.faintDialog.getCustomView(); + if (customView != null) { + View hpBarView = customView.findViewById(R.id.hpBar); + + ValueBarBinding hpBar = DataBindingUtil.bind(hpBarView); + hpBar.setPartyMembers(true); + AvatarWithBarsViewModel.setHpBarData(hpBar, User.getStats(), this); + + ImageView avatarView = (ImageView)customView.findViewById(R.id.avatarView); + UserPicture userPicture = new UserPicture(User, this, false, false); + userPicture.setPictureOn(avatarView); + } + + this.faintDialog.show(); + } + + } +} \ No newline at end of file diff --git a/Habitica/src/com/habitrpg/android/habitica/TasksFragment.java b/Habitica/src/com/habitrpg/android/habitica/TasksFragment.java new file mode 100644 index 000000000..ab78fb537 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/TasksFragment.java @@ -0,0 +1,209 @@ +package com.habitrpg.android.habitica; + +import android.os.Bundle; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.habitrpg.android.habitica.helpers.TagsHelper; +import com.habitrpg.android.habitica.ui.adapter.HabitItemRecyclerViewAdapter; +import com.habitrpg.android.habitica.ui.adapter.IReceiveNewEntries; +import com.habitrpg.android.habitica.ui.fragments.TaskRecyclerViewFragment; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; +import com.mikepenz.materialdrawer.Drawer; +import com.mikepenz.materialdrawer.DrawerBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import retrofit.Callback; +import retrofit.RetrofitError; +import retrofit.client.Response; + +/** + * Created by admin on 18/11/15. + */ +public class TasksFragment extends BaseFragment { + + public TabLayout tabLayout; + public ViewPager viewPager; + + Drawer filterDrawer; + + Map ViewFragmentsDictionary = new HashMap<>(); + + private TagsHelper tagsHelper; + private ContentCache contentCache; + + public void setActivity(MainActivity activity) { + super.setActivity(activity); + contentCache = new ContentCache(mAPIHelper.apiService); + } + + @Override + public void setTabLayout(TabLayout tabLayout) { + this.tabLayout = tabLayout; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View v = inflater.inflate(R.layout.fragment_tasks, container, false); + + viewPager = (ViewPager) v.findViewById(R.id.view_pager); + + filterDrawer = new DrawerBuilder() + .withActivity(activity) + .withDrawerGravity(Gravity.RIGHT) + .withCloseOnClick(false) + .append(activity.drawer); + + viewPager.setCurrentItem(0); + this.tagsHelper = new TagsHelper(); + + loadTaskLists(); + + return v; + } + + public void loadTaskLists() { + android.support.v4.app.FragmentManager fragmentManager = getChildFragmentManager(); + + viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { + + int oldPosition = -1; + + @Override + public Fragment getItem(int position) { + int layoutOfType; + TaskRecyclerViewFragment fragment; + HabitItemRecyclerViewAdapter adapter; + + switch (position) { + case 0: + layoutOfType = R.layout.habit_item_card; + fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_HABIT, TasksFragment.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.HabitViewHolder.class, activity), Task.TYPE_HABIT); + + break; + case 1: + layoutOfType = R.layout.daily_item_card; + adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_DAILY, TasksFragment.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.DailyViewHolder.class, activity); + if (user != null) { + adapter.dailyResetOffset = user.getPreferences().getDayStart(); + } + fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_DAILY); + break; + case 3: + layoutOfType = R.layout.reward_item_card; + adapter = new HabitItemRecyclerViewAdapter(Task.TYPE_REWARD, TasksFragment.this.tagsHelper, + layoutOfType, HabitItemRecyclerViewAdapter.RewardViewHolder.class, activity, + new HabitItemRecyclerViewAdapter.IAdditionalEntries() { + @Override + public void GetAdditionalEntries(final IReceiveNewEntries callBack) { + + // request buyable gear + mAPIHelper.apiService.getInventoryBuyableGear(new Callback>() { + @Override + public void success(List itemDatas, Response response) { + + // get itemdata list + ArrayList itemKeys = new ArrayList(); + for (ItemData item : itemDatas) { + itemKeys.add(item.key); + } + itemKeys.add("potion"); + + contentCache.GetItemDataList(itemKeys, new ContentCache.GotContentEntryCallback>() { + @Override + public void GotObject(List obj) { + ArrayList buyableItems = new ArrayList(); + + for (ItemData item : obj) { + Task reward = new Task(); + reward.text = item.text; + reward.notes = item.notes; + reward.value = item.value; + reward.setType("reward"); + reward.specialTag = "item"; + reward.setId(item.key); + + buyableItems.add(reward); + } + + callBack.GotAdditionalItems(buyableItems); + + } + }); + + + } + + @Override + public void failure(RetrofitError error) { + + } + }); + + } + }); + + + fragment = TaskRecyclerViewFragment.newInstance(adapter, Task.TYPE_REWARD); + break; + default: + layoutOfType = R.layout.todo_item_card; + fragment = TaskRecyclerViewFragment.newInstance(new HabitItemRecyclerViewAdapter(Task.TYPE_TODO, TasksFragment.this.tagsHelper, layoutOfType, HabitItemRecyclerViewAdapter.TodoViewHolder.class, activity), Task.TYPE_TODO); + } + + ViewFragmentsDictionary.put(position, fragment); + + return fragment; + } + + @Override + public int getCount() { + return 4; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "Habits"; + case 1: + return "Dailies"; + case 2: + return "Todos"; + case 3: + return "Rewards"; + } + return ""; + } + }); + + + tabLayout.setupWithViewPager(viewPager); + + } + + public void updateUserData(HabitRPGUser user) { + super.updateUserData(user); + if (this.user != null) { + TaskRecyclerViewFragment fragment = ViewFragmentsDictionary.get(2); + if (fragment != null) { + HabitItemRecyclerViewAdapter adapter =(HabitItemRecyclerViewAdapter)fragment.mAdapter; + adapter.dailyResetOffset = this.user.getPreferences().getDayStart(); + } + } + } +} diff --git a/Habitica/src/com/habitrpg/android/habitica/TavernActivity.java b/Habitica/src/com/habitrpg/android/habitica/TavernActivity.java index 4db05f2d0..ba775d52b 100644 --- a/Habitica/src/com/habitrpg/android/habitica/TavernActivity.java +++ b/Habitica/src/com/habitrpg/android/habitica/TavernActivity.java @@ -69,9 +69,7 @@ public class TavernActivity extends AppCompatActivity { } accountHeader = MainDrawerBuilder.CreateDefaultAccountHeader(this).build(); - Drawer drawer = MainDrawerBuilder.CreateDefaultBuilderSettings(this, toolbar, accountHeader) - .withSelectedItem(2) - .build(); + avatarInHeader = new AvatarWithBarsViewModel(this, avatarHeader); diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/MainDrawerBuilder.java b/Habitica/src/com/habitrpg/android/habitica/ui/MainDrawerBuilder.java index 03ca582d0..332b8b958 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/MainDrawerBuilder.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/MainDrawerBuilder.java @@ -6,10 +6,14 @@ import android.support.v7.widget.Toolbar; import android.view.View; import com.habitrpg.android.habitica.AboutActivity; +import com.habitrpg.android.habitica.BaseFragment; import com.habitrpg.android.habitica.GemPurchaseActivity; import com.habitrpg.android.habitica.MainActivity; +import com.habitrpg.android.habitica.PartyFragment; +import com.habitrpg.android.habitica.TaskActivity; import com.habitrpg.android.habitica.PartyActivity; import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.TasksFragment; import com.habitrpg.android.habitica.TavernActivity; import com.habitrpg.android.habitica.prefs.PrefsActivity; import com.mikepenz.materialdrawer.AccountHeader; @@ -19,11 +23,11 @@ import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.model.DividerDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem; -import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.SectionDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IProfile; +import java.lang.reflect.Constructor; import java.util.HashMap; @@ -40,16 +44,7 @@ public class MainDrawerBuilder { static final int SIDEBAR_SETTINGS = 6; static final int SIDEBAR_ABOUT = 7; - private static HashMap ClassMap = new HashMap<>(); - static { - ClassMap.put(SIDEBAR_TASKS, MainActivity.class); - ClassMap.put(SIDEBAR_TAVERN, TavernActivity.class); - ClassMap.put(SIDEBAR_PARTY, PartyActivity.class); - ClassMap.put(SIDEBAR_PURCHASE, GemPurchaseActivity.class); - ClassMap.put(SIDEBAR_SETTINGS, PrefsActivity.class); - ClassMap.put(SIDEBAR_ABOUT, AboutActivity.class); - } public static AccountHeaderBuilder CreateDefaultAccountHeader(final Activity activity) { AccountHeaderBuilder builder = new AccountHeaderBuilder() @@ -69,7 +64,7 @@ public class MainDrawerBuilder { } - public static DrawerBuilder CreateDefaultBuilderSettings(final Activity activity, Toolbar toolbar, AccountHeader accountHeader) { + public static DrawerBuilder CreateDefaultBuilderSettings(final MainActivity activity, Toolbar toolbar, AccountHeader accountHeader) { DrawerBuilder builder = new DrawerBuilder() .withActivity(activity); @@ -106,13 +101,21 @@ public class MainDrawerBuilder { public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { // do something with the clicked item :D - Class selectedClass = ClassMap.get(drawerItem.getIdentifier()); + BaseFragment fragment = null; - if (selectedClass != null && activity.getClass() != selectedClass) { - activity.startActivity(new Intent(activity, selectedClass)); - return false; - } else if (selectedClass != null) { - //same item was clicked again + switch (drawerItem.getIdentifier()) { + case SIDEBAR_TASKS: { + fragment = new TasksFragment(); + break; + } + case SIDEBAR_PARTY: { + fragment = new PartyFragment(); + break; + } + } + + if (fragment != null) { + activity.displayFragment(fragment); return false; } @@ -121,14 +124,6 @@ public class MainDrawerBuilder { } }); - Class activityClass = activity.getClass(); - for (java.util.Map.Entry entry: ClassMap.entrySet()) { - if(entry.getValue() == activityClass){ - builder.withSelectedItem(entry.getKey()); - } - } - - return builder; } } diff --git a/Habitica/src/com/habitrpg/android/habitica/widget/UpdateWidgetService.java b/Habitica/src/com/habitrpg/android/habitica/widget/UpdateWidgetService.java index bcdc57f6d..d51924aa8 100644 --- a/Habitica/src/com/habitrpg/android/habitica/widget/UpdateWidgetService.java +++ b/Habitica/src/com/habitrpg/android/habitica/widget/UpdateWidgetService.java @@ -11,7 +11,7 @@ import android.widget.RemoteViews; import com.habitrpg.android.habitica.APIHelper; import com.habitrpg.android.habitica.HostConfig; -import com.habitrpg.android.habitica.MainActivity; +import com.habitrpg.android.habitica.TaskActivity; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback; import com.habitrpg.android.habitica.prefs.PrefsActivity; @@ -64,7 +64,7 @@ public class UpdateWidgetService extends Service implements HabitRPGUserCallback PendingIntent updateIntent = PendingIntent.getBroadcast(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent); - Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class); + Intent openAppIntent = new Intent(this.getApplicationContext(), TaskActivity.class); PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp); appWidgetManager.updateAppWidget(widgetId, remoteViews); @@ -95,7 +95,7 @@ public class UpdateWidgetService extends Service implements HabitRPGUserCallback remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent); //If user click on life and xp: open the app - Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class); + Intent openAppIntent = new Intent(this.getApplicationContext(), TaskActivity.class); PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.LL_header, openApp); remoteViews.setOnClickPendingIntent(R.id.IMG_ProfilePicture, openApp); diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java index 4ece76646..d42eed8e8 100644 --- a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java @@ -36,7 +36,7 @@ public interface ApiService { @GET("/content") void getContent(Callback contentResultCallback); - /* User API */ + /* user API */ @GET("/user/") void getUser(Callback habitRPGUserCallback);