Merge branch 'develop' of github.com:HabitRPG/habitrpg-android into develop

# Conflicts:
#	Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GroupInformationFragment.java
#	Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java
This commit is contained in:
Phillip Thelen 2016-03-05 14:56:24 +01:00
commit db6a7e2bdb
12 changed files with 475 additions and 3 deletions

View file

@ -0,0 +1 @@
ALTER TABLE Quest ADD COLUMN RSVPNeeded bool;

View file

@ -6,6 +6,7 @@
<data>
<import type="com.magicmicky.habitrpgwrapper.lib.models.Group" />
<import type="com.magicmicky.habitrpgwrapper.lib.models.QuestContent" />
<import type="com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser" />
<import type="android.view.View" />
<import type="android.text.Html"/>
@ -16,6 +17,10 @@
<variable
name="quest"
type="QuestContent" />
<variable
name="user"
type="HabitRPGUser" />
</data>
@ -118,6 +123,99 @@
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:visibility="@{quest != null ? View.VISIBLE : View.GONE}">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/questMemberView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:visibility="@{party.quest.active? View.VISIBLE : View.GONE}">
<Button
android:id="@+id/btnQuestAbort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_warning"
android:text="@string/quest.abort"
android:textColor="@android:color/white"
android:visibility="@{(party.quest != null &amp;&amp; user.getId().equals(party.quest.leader))? View.VISIBLE : View.GONE}" />
<Button
android:id="@+id/btnQuestLeave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_warning"
android:text="@string/quest.leave"
android:textColor="@android:color/white"
android:visibility="@{(!user.getId().equals(party.quest.leader) &amp;&amp; party.quest.members.containsKey(user.getId()))? View.VISIBLE : View.GONE}" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:visibility="@{!party.quest.active? View.VISIBLE : View.GONE}">
<Button
android:id="@+id/btnQuestAccept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_success"
android:text="@string/quest.accept"
android:textColor="@android:color/white"
android:visibility="@{user.getParty().getQuest().RSVPNeeded? View.VISIBLE : View.GONE}" />
<Button
android:id="@+id/btnQuestReject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_danger"
android:text="@string/quest.reject"
android:textColor="@android:color/white"
android:visibility="@{user.getParty().getQuest().RSVPNeeded? View.VISIBLE : View.GONE}" />
<Button
android:id="@+id/btnQuestBegin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_warning"
android:text="@string/quest.begin"
android:textColor="@android:color/white"
android:visibility="@{user.getId().equals(party.quest.leader) ? View.VISIBLE : View.GONE}" />
<Button
android:id="@+id/btnQuestCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/btn_danger"
android:text="@string/quest.cancel"
android:textColor="@android:color/white"
android:visibility="@{user.getId().equals(party.quest.leader) ? View.VISIBLE : View.GONE}" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</layout>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="username"
android:layout_weight="1" />
<TextView
android:id="@+id/rsvpneeded"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="response" />
</LinearLayout>
</LinearLayout>

View file

@ -91,4 +91,10 @@
<color name="checkbox_fill">#50ffffff</color>
<color name="checkbox_checked_fill">#c8ffffff</color>
<color name="checkbox_stroke">#32000000</color>
<!-- buttons -->
<color name="btn_success">#ff5cb85c</color>
<color name="btn_warning">#fff0ad4e</color>
<color name="btn_danger">#ffd9534f</color>
</resources>

View file

@ -161,6 +161,12 @@
<string name="purchase_button">Purchase</string>
<string name="purchase_set_title" formatted="false">Purchase set %s</string>
<string name="due_date">Due Date</string>
<string name="quest.accept">Accept</string>
<string name="quest.reject">Reject</string>
<string name="quest.begin">Begin</string>
<string name="quest.cancel">Cancel</string>
<string name="quest.abort">Abort</string>
<string name="quest.leave">Leave Quest</string>
<string name="version_info" formatted="false">Version %s (%d)</string>

View file

@ -10,5 +10,5 @@ public class HabitDatabase {
public static final String NAME = "Habitica";
public static final int VERSION = 11;
public static final int VERSION = 12;
}

View file

@ -0,0 +1,89 @@
package com.habitrpg.android.habitica.ui.adapter;
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.TextView;
import com.habitrpg.android.habitica.R;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by Negue on 22.09.2015.
*/
public class PartyMemberQuestRecyclerViewAdapter extends RecyclerView.Adapter<PartyMemberQuestRecyclerViewAdapter.MemberQuestViewHolder> {
Group group;
public void setGroup(Group group) {
Log.d("PartyMemberQuestFrag", "set group");
this.group = group;
this.notifyDataSetChanged();
}
@Override
public MemberQuestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.party_member_quest, parent, false);
Log.d("PartyMemberQuestFrag", "inflated");
return new MemberQuestViewHolder(view);
}
@Override
public void onBindViewHolder(MemberQuestViewHolder holder, int position) {
Log.d("PartyMemberQuestFrag", "call binder");
holder.bind(group.members.get(position));
}
@Override
public int getItemCount() {
Log.d("PartyMemberQuestFrag", "group " + ((group == null)? 0 : group.memberCount));
return (group == null)? 0 : group.memberCount;
}
class MemberQuestViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.username)
TextView userName;
@Bind(R.id.rsvpneeded)
TextView rsvpNeeded;
public MemberQuestViewHolder(View itemView) {
super(itemView);
Log.d("PartyMemberQuestFrag", "VH init");
ButterKnife.bind(this, itemView);
Log.d("PartyMemberFrag", "VH init");
}
public void bind(HabitRPGUser user) {
Log.d("PartyMemberQuestFrag", "bind " + user.getProfile().getName());
android.content.Context ctx = itemView.getContext();
userName.setText(user.getProfile().getName());
Boolean rsvpneeded = group.quest.members.get(user.getId());
if(rsvpneeded == null){
rsvpNeeded.setText("Pending");
}else if(rsvpneeded == true){
rsvpNeeded.setText("Accepted");
}else{ // rsvpneeded == false
rsvpNeeded.setText("Rejected");
}
}
}
}

View file

@ -1,18 +1,35 @@
package com.habitrpg.android.habitica.ui.fragments.social;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
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.APIHelper;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.FragmentGroupInfoBinding;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.QuestContent;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import de.greenrobot.event.EventBus;
import de.greenrobot.event.EventBusException;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
/**
* Created by Negue on 16.09.2015.
*/
@ -21,15 +38,22 @@ public class GroupInformationFragment extends Fragment {
private View view;
FragmentGroupInfoBinding viewBinding;
APIHelper mAPIHelper;
@Bind(R.id.questMemberView)
LinearLayout questMemberView;
private Group group;
private HabitRPGUser user;
public static GroupInformationFragment newInstance(Group group) {
public static GroupInformationFragment newInstance(Group group, HabitRPGUser user, APIHelper mAPIHelper) {
Bundle args = new Bundle();
GroupInformationFragment fragment = new GroupInformationFragment();
fragment.setArguments(args);
fragment.group = group;
fragment.user = user;
fragment.mAPIHelper = mAPIHelper;
return fragment;
}
@ -44,18 +68,34 @@ public class GroupInformationFragment extends Fragment {
view = inflater.inflate(R.layout.fragment_group_info, container, false);
viewBinding = DataBindingUtil.bind(view);
if (user != null) {
viewBinding.setUser(user);
}
if (group != null) {
setGroup(group);
}
ButterKnife.bind(this, view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
public void setGroup(Group group) {
if (viewBinding != null) {
viewBinding.setGroup(group);
}
if (questMemberView != null) {
updateQuestMember(group);
}
this.group = group;
}
public void setQuestContent(QuestContent quest) {
@ -63,4 +103,183 @@ public class GroupInformationFragment extends Fragment {
viewBinding.setQuest(quest);
}
}
private void updateQuestMember(Group group) {
questMemberView.removeAllViewsInLayout();
if (group.quest.key == null) return;
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (HabitRPGUser member : group.members) {
final LinearLayout itemView = (LinearLayout) layoutInflater.inflate(R.layout.party_member_quest, null);
TextView questResponse = (TextView) itemView.findViewById(R.id.rsvpneeded);
TextView userName = (TextView) itemView.findViewById(R.id.username);
if (group.quest.leader.equals(member.getId()))
userName.setText("* " + member.getProfile().getName());
else
userName.setText(member.getProfile().getName());
if (!group.quest.members.containsKey(member.getId()))
continue;
Boolean questresponse = group.quest.members.get(member.getId());
if (group.quest.active) {
questResponse.setText("");
} else if (questresponse == null) {
questResponse.setText("Pending");
} else if (questresponse.booleanValue() == true) {
questResponse.setText("Accepted");
questResponse.setTextColor(Color.parseColor("#2db200"));
} else if (questresponse.booleanValue() == false) {
questResponse.setText("Rejected");
questResponse.setTextColor(Color.parseColor("#b30409"));
}
questMemberView.post(new Runnable() {
@Override
public void run() {
questMemberView.addView(itemView);
}
});
}
}
@OnClick(R.id.btnQuestAccept)
public void onQuestAccept() {
mAPIHelper.apiService.acceptQuest(group.id, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
user.getParty().getQuest().RSVPNeeded = false;
group.quest.members.put(user.getId(), true);
setGroup(group);
viewBinding.setUser(user);
}
@Override
public void failure(RetrofitError error) {
}
});
}
@OnClick(R.id.btnQuestReject)
public void onQuestReject() {
mAPIHelper.apiService.rejectQuest(group.id, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
user.getParty().getQuest().RSVPNeeded = false;
group.quest.members.put(user.getId(), false);
setGroup(group);
viewBinding.setUser(user);
}
@Override
public void failure(RetrofitError error) {
}
});
}
@OnClick(R.id.btnQuestLeave)
public void onQuestLeave() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setMessage("Are you sure you want to leave the active quest? All your quest progress will be lost.")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mAPIHelper.apiService.leaveQuest(group.id, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
group.quest.members.remove(user.getId());
setGroup(group);
}
@Override
public void failure(RetrofitError error) {
}
});
}
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
}
@OnClick(R.id.btnQuestBegin)
public void onQuestBegin() {
mAPIHelper.apiService.forceStartQuest(group.id, group, new Callback<Group>() {
@Override
public void success(Group group, Response response) {
setGroup(group);
}
@Override
public void failure(RetrofitError error) {
}
});
}
@OnClick(R.id.btnQuestCancel)
public void onQuestCancel() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setMessage("Are you sure you want to cancel this quest? All invitation acceptances will be lost. The quest owner will retain possession of the quest scroll.")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mAPIHelper.apiService.cancelQuest(group.id, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
setGroup(group);
setQuestContent(null);
}
@Override
public void failure(RetrofitError error) {
}
});
}
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
}
@OnClick(R.id.btnQuestAbort)
public void onQuestAbort() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setMessage("Are you sure you want to abort this mission? It will abort it for everyone in your party and all progress will be lost. The quest scroll will be returned to the quest owner.")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mAPIHelper.apiService.abortQuest(group.id, new Callback<Group>() {
@Override
public void success(Group group, Response response) {
setGroup(group);
setQuestContent(null);
}
@Override
public void failure(RetrofitError error) {
}
});
}
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
}
}

View file

@ -123,7 +123,7 @@ public class PartyFragment extends BaseMainFragment {
switch (position) {
case 0: {
fragment = groupInformationFragment = GroupInformationFragment.newInstance(group);
fragment = groupInformationFragment = GroupInformationFragment.newInstance(group, user, mAPIHelper);
break;
}
case 1: {

View file

@ -141,4 +141,22 @@ public interface ApiService {
@POST("/user/batch-update")
void batchOperation(@Body List<Map<String,Object>> operations, Callback<HabitRPGUser> cb);
@POST("/groups/{gid}/questAccept")
void acceptQuest(@Path("gid") String groupId, Callback<Void> cb);
@POST("/groups/{gid}/questReject")
void rejectQuest(@Path("gid") String groupId, Callback<Void> cb);
@POST("/groups/{gid}/questCancel")
void cancelQuest(@Path("gid") String groupId, Callback<Void> cb);
@POST("/groups/{gid}/questAccept?force=true")
void forceStartQuest(@Path("gid") String groupId, @Body Group group, Callback<Group> cb);
@POST("/groups/{gid}/questAbort")
void abortQuest(@Path("gid") String groupId, Callback<Group> cb);
@POST("/groups/{gid}/questLeave")
void leaveQuest(@Path("gid") String groupId, Callback<Void> cb);
}

View file

@ -21,6 +21,7 @@ public class HabitRPGUser extends BaseModel {
@Column
@PrimaryKey
@SerializedName("_id")
private String id;
List<Task> dailys;

View file

@ -25,6 +25,9 @@ public class Quest extends BaseModel {
@Column
public String leader;
@Column
public boolean RSVPNeeded;
public HashMap<String, Boolean> members;
@ForeignKey(references = {@ForeignKeyReference(columnName = "progress_id",