diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index a4497923a..633ac7c85 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -48,7 +48,10 @@ - + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/skill_task_item_card.xml b/Habitica/res/layout/skill_task_item_card.xml new file mode 100644 index 000000000..0ece71509 --- /dev/null +++ b/Habitica/res/layout/skill_task_item_card.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 095745a42..f966c8b0b 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -179,4 +179,5 @@ Profile Image %d MP + You used %1$s for %2$d mana. \ No newline at end of file diff --git a/Habitica/src/com/habitrpg/android/habitica/SkillTasksActivity.java b/Habitica/src/com/habitrpg/android/habitica/SkillTasksActivity.java new file mode 100644 index 000000000..6d1c8f966 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/SkillTasksActivity.java @@ -0,0 +1,109 @@ +package com.habitrpg.android.habitica; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.habitrpg.android.habitica.ui.adapter.HabitItemRecyclerViewAdapter; +import com.habitrpg.android.habitica.ui.adapter.SkillTasksRecyclerViewAdapter; +import com.habitrpg.android.habitica.ui.fragments.SkillTasksRecyclerViewFragment; +import com.habitrpg.android.habitica.ui.fragments.TaskRecyclerViewFragment; +import com.habitrpg.android.habitica.ui.fragments.TasksFragment; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; + +import java.util.HashMap; +import java.util.Map; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Created by viirus on 28/11/15. + */ +public class SkillTasksActivity extends AppCompatActivity { + @InjectView(R.id.viewpager) + public ViewPager viewPager; + + @InjectView(R.id.tab_layout) + public TabLayout tabLayout; + + Map ViewFragmentsDictionary = new HashMap<>(); + protected HabitRPGUser user; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_skill_tasks); + + ButterKnife.inject(this); + + loadTaskLists(); + } + + public void loadTaskLists() { + android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); + + viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) { + + @Override + public Fragment getItem(int position) { + SkillTasksRecyclerViewFragment fragment; + + switch (position) { + case 0: + fragment = SkillTasksRecyclerViewFragment.newInstance(new SkillTasksRecyclerViewAdapter(Task.TYPE_HABIT, SkillTasksActivity.this), Task.TYPE_HABIT); + break; + case 1: + fragment = SkillTasksRecyclerViewFragment.newInstance(new SkillTasksRecyclerViewAdapter(Task.TYPE_DAILY, SkillTasksActivity.this), Task.TYPE_DAILY); + + break; + default: + fragment = SkillTasksRecyclerViewFragment.newInstance(new SkillTasksRecyclerViewAdapter(Task.TYPE_TODO, SkillTasksActivity.this), Task.TYPE_TODO); + } + + ViewFragmentsDictionary.put(position, fragment); + + return fragment; + } + + @Override + public int getCount() { + return 3; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "Habits"; + case 1: + return "Dailies"; + case 2: + return "Todos"; + } + return ""; + } + }); + + + tabLayout.setupWithViewPager(viewPager); + } + + public void taskSelected(String taskId) { + Intent resultIntent = new Intent(); + resultIntent.putExtra("task_id", taskId); + setResult(Activity.RESULT_OK, resultIntent); + finish(); + } +} diff --git a/Habitica/src/com/habitrpg/android/habitica/callbacks/SkillCallback.java b/Habitica/src/com/habitrpg/android/habitica/callbacks/SkillCallback.java new file mode 100644 index 000000000..24628f8e4 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/callbacks/SkillCallback.java @@ -0,0 +1,42 @@ +package com.habitrpg.android.habitica.callbacks; + +import android.util.Log; + +import com.crashlytics.android.Crashlytics; +import com.habitrpg.android.habitica.events.SkillUsedEvent; +import com.habitrpg.android.habitica.events.TaskCreatedEvent; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.Skill; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; + +import de.greenrobot.event.EventBus; +import retrofit.Callback; +import retrofit.RetrofitError; +import retrofit.client.Response; + +/** + * Created by viirus on 28/11/15. + */ +public class SkillCallback implements Callback { + + private Skill usedSkill; + private final HabitRPGUserCallback.OnUserReceived callback; + + public SkillCallback(HabitRPGUserCallback.OnUserReceived callback, Skill usedSkill) { + this.callback = callback; + this.usedSkill = usedSkill; + } + + @Override + public void success(HabitRPGUser habitRPGUser, Response response) { + habitRPGUser.async().save(); + EventBus.getDefault().post(new SkillUsedEvent(this.usedSkill, habitRPGUser.getStats().getMp())); + callback.onUserReceived(habitRPGUser); + } + + @Override + public void failure(RetrofitError error) { + Crashlytics.logException(error); + callback.onUserFail(); + } +} diff --git a/Habitica/src/com/habitrpg/android/habitica/events/SkillUsedEvent.java b/Habitica/src/com/habitrpg/android/habitica/events/SkillUsedEvent.java new file mode 100644 index 000000000..58e787dbc --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/events/SkillUsedEvent.java @@ -0,0 +1,17 @@ +package com.habitrpg.android.habitica.events; + +import com.magicmicky.habitrpgwrapper.lib.models.Skill; + +/** + * Created by viirus on 28/11/15. + */ +public class SkillUsedEvent { + + public Skill usedSkill; + public Double newMana; + + public SkillUsedEvent(Skill usedSkill, Double newMana) { + this.usedSkill = usedSkill; + this.newMana = newMana; + } +} diff --git a/Habitica/src/com/habitrpg/android/habitica/events/commands/UseSkillCommand.java b/Habitica/src/com/habitrpg/android/habitica/events/commands/UseSkillCommand.java new file mode 100644 index 000000000..2827743d2 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/events/commands/UseSkillCommand.java @@ -0,0 +1,11 @@ +package com.habitrpg.android.habitica.events.commands; + +import com.magicmicky.habitrpgwrapper.lib.models.Skill; + +/** + * Created by viirus on 28/11/15. + */ +public class UseSkillCommand { + + public Skill skill; +} diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java new file mode 100644 index 000000000..e1e32f770 --- /dev/null +++ b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java @@ -0,0 +1,168 @@ +package com.habitrpg.android.habitica.ui.adapter; + +import android.app.Activity; +import android.content.Context; +import android.databinding.DataBindingUtil; +import android.databinding.ObservableArrayList; +import android.os.Handler; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.SkillTasksActivity; +import com.habitrpg.android.habitica.databinding.SkillTaskItemCardBinding; +import com.habitrpg.android.habitica.events.TaskLongPressedEvent; +import com.habitrpg.android.habitica.events.TaskTappedEvent; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; +import com.raizlabs.android.dbflow.sql.builder.Condition; +import com.raizlabs.android.dbflow.sql.language.OrderBy; +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.UUID; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import de.greenrobot.event.EventBus; + + +public class SkillTasksRecyclerViewAdapter extends RecyclerView.Adapter { + + + String taskType; + private ObservableArrayList observableContent; + SkillTasksActivity activity; + + static final int TYPE_CELL = 1; + private RecyclerView.Adapter parentAdapter; + + public SkillTasksRecyclerViewAdapter(String taskType, SkillTasksActivity activity) { + this.setHasStableIds(true); + this.taskType = taskType; + this.activity = activity; + + this.loadContent(); + + } + + public void setParentAdapter(RecyclerView.Adapter parentAdapter) { + this.parentAdapter = parentAdapter; + } + + @Override + public int getItemViewType(int position) { + switch (position) { + default: + return TYPE_CELL; + } + } + + @Override + public long getItemId(int position) { + Task task = observableContent.get(position); + if (task.getId() != null && task.getId().length() == 36) { + return UUID.fromString(task.getId()).getMostSignificantBits(); + } + return UUID.randomUUID().getMostSignificantBits(); + } + + @Override + public int getItemCount() { + return observableContent.size(); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = null; + view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.skill_task_item_card, parent, false); + return new SkillTasksRecyclerViewAdapter.ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + Task item = observableContent.get(position); + + holder.bindHolder(item, position); + } + + // region ViewHolders + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + + protected android.content.res.Resources resources; + + public Task task; + + SkillTaskItemCardBinding binding; + + @InjectView(R.id.notesTextView) + TextView notesTextView; + + public ViewHolder(View itemView) { + super(itemView); + + itemView.setOnClickListener(this); + itemView.setClickable(true); + + ButterKnife.inject(this, itemView); + binding = DataBindingUtil.bind(itemView); + + resources = itemView.getResources(); + } + + public void bindHolder(Task habitItem, int position) { + double itemvalue = habitItem.getValue(); + task = habitItem; + if (habitItem.notes == null || habitItem.notes.length() == 0) { + notesTextView.setHeight(0); + } else { + notesTextView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + } + binding.setTask(task); + } + + @Override + public void onClick(View v) { + if (v != itemView) + return; + activity.taskSelected(task.getId()); + } + + } + + // endregion + + public void loadContent() { + this.loadContent(false); + } + + public void loadContent(boolean forced) { + + if (this.observableContent == null || forced) { + + this.observableContent = new ObservableArrayList<>(); + + this.observableContent.addAll(new Select().from(Task.class) + .where(Condition.column("type").eq(this.taskType)) + .and(Condition.CombinedCondition + .begin(Condition.column("completed").eq(false)) + .or(Condition.column("type").eq("daily")) + ) + .orderBy(OrderBy.columns("dateCreated").descending()) + .queryList()); + } + + if (parentAdapter != null) { + parentAdapter.notifyDataSetChanged(); + } else { + notifyDataSetChanged(); + } + } +} diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java index 6e57b2c09..7e19997a2 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java @@ -17,6 +17,7 @@ import android.widget.TextView; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.databinding.ValueBarBinding; +import com.habitrpg.android.habitica.events.TaskTappedEvent; import com.habitrpg.android.habitica.events.commands.CopyChatAsTodoCommand; import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand; import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand; @@ -24,6 +25,7 @@ import com.habitrpg.android.habitica.events.commands.OpenNewPMActivityCommand; import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand; import com.habitrpg.android.habitica.events.commands.ToggleInnCommand; import com.habitrpg.android.habitica.events.commands.ToggleLikeMessageCommand; +import com.habitrpg.android.habitica.events.commands.UseSkillCommand; import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; import com.habitrpg.android.habitica.ui.helpers.ViewHelper; @@ -59,6 +61,11 @@ public class SkillsRecyclerViewAdapter extends RecyclerView.Adapter habitRPGUserCallback); + @POST("/user/class/cast/{skill}") + void useSkill(@Path("skill") String skillName, @Query("targetType") String targetType, @Query("targetId") String targetId, Callback habitRPGUserCallback); + + @POST("/user/class/cast/{skill}") + void useSkill(@Path("skill") String skillName, @Query("targetType") String targetType, Callback habitRPGUserCallback); + /* Group API */ @GET("/groups")