diff --git a/Habitica/res/layout/challenge_item.xml b/Habitica/res/layout/challenge_item.xml
index 805e0e049..74f5c17f6 100644
--- a/Habitica/res/layout/challenge_item.xml
+++ b/Habitica/res/layout/challenge_item.xml
@@ -2,10 +2,10 @@
+ android:layout_margin="5dp"
+ android:clickable="true">
+ android:layout_height="wrap_content"
+ android:textStyle="bold" />
+ android:maxLines="3" />
-
-
- android:ellipsize="middle"
- android:lines="1" />
-
+
+
+ android:gravity="right|fill_vertical">
+
+
+
+
+
+
+
+
+
+ android:baselineAligned="false">
+ android:layout_weight="1">
-
-
-
-
-
+ android:layout_height="match_parent"
+ android:gravity="start|fill_vertical"
+ android:text="@string/leave"
+ android:textColor="@color/md_red_400" />
-
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml
index 22960f45d..7d0d2b038 100644
--- a/Habitica/res/values/strings.xml
+++ b/Habitica/res/values/strings.xml
@@ -438,4 +438,8 @@ To start, which parts of your life do you want to improve?
Change Habitica\'s Audio Theme
by %s
Challenge Details
+ Are you sure?
+ Are you sure you want to leave the Challenge "%s"?
+ My Challenges
+ Public
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/JoinChallengeCommand.java b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/JoinChallengeCommand.java
new file mode 100644
index 000000000..33417ab4f
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/JoinChallengeCommand.java
@@ -0,0 +1,11 @@
+package com.habitrpg.android.habitica.events.commands;
+
+public class JoinChallengeCommand {
+ public String challengeId;
+
+ public JoinChallengeCommand(String challengeId){
+ this.challengeId = challengeId;
+ }
+}
+
+
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/LeaveChallengeCommand.java b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/LeaveChallengeCommand.java
new file mode 100644
index 000000000..f7a5e59c5
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/LeaveChallengeCommand.java
@@ -0,0 +1,9 @@
+package com.habitrpg.android.habitica.events.commands;
+
+public class LeaveChallengeCommand {
+ public String challengeId;
+
+ public LeaveChallengeCommand(String challengeId){
+ this.challengeId = challengeId;
+ }
+}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeDetailActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeDetailActivity.java
index e756c0fcc..e35ec1cbb 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeDetailActivity.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeDetailActivity.java
@@ -3,18 +3,23 @@ package com.habitrpg.android.habitica.ui.activities;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentTransaction;
+import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.components.AppComponent;
-import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter.ChallengeViewHolder;
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeTasksFragment;
+import com.magicmicky.habitrpgwrapper.lib.models.Challenge;
import javax.inject.Inject;
import butterknife.BindView;
+import butterknife.ButterKnife;
public class ChallengeDetailActivity extends BaseActivity {
@@ -73,4 +78,51 @@ public class ChallengeDetailActivity extends BaseActivity {
protected void injectActivity(AppComponent component) {
component.inject(this);
}
+
+ public static class ChallengeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ @BindView(R.id.challenge_name)
+ TextView challengeName;
+
+ @BindView(R.id.challenge_description)
+ TextView challengeDescription;
+
+
+ @BindView(R.id.memberCountTextView)
+ TextView memberCountTextView;
+
+ @BindView(R.id.gem_prize_layout)
+ LinearLayout gem_prize_layout;
+
+ @BindView(R.id.gemPrizeTextView)
+ TextView gemPrizeTextView;
+
+ private Challenge challenge;
+
+ public ChallengeViewHolder(View itemView) {
+ super(itemView);
+
+ ButterKnife.bind(this, itemView);
+ }
+
+ public void bind(Challenge challenge) {
+ this.challenge = challenge;
+
+ challengeName.setText(challenge.name);
+ challengeDescription.setText(challenge.description);
+
+ memberCountTextView.setText(challenge.memberCount + "");
+
+ if (challenge.prize == 0) {
+ gem_prize_layout.setVisibility(View.GONE);
+ } else {
+ gem_prize_layout.setVisibility(View.VISIBLE);
+ gemPrizeTextView.setText(challenge.prize + "");
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+
+ }
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java
index 14c21dea8..abcc90884 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java
@@ -1,16 +1,22 @@
package com.habitrpg.android.habitica.ui.adapter.social;
+import android.content.Context;
+import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
+import com.habitrpg.android.habitica.events.commands.JoinChallengeCommand;
+import com.habitrpg.android.habitica.events.commands.LeaveChallengeCommand;
+import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand;
import com.habitrpg.android.habitica.events.commands.ShowChallengeTasksCommand;
+import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils;
import com.magicmicky.habitrpgwrapper.lib.models.Challenge;
-import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import org.greenrobot.eventbus.EventBus;
@@ -51,6 +57,11 @@ public class ChallengesListViewAdapter extends RecyclerView.Adapter {
+ EventBus.getDefault().post(new LeaveChallengeCommand(challenge.id));
+ }).setNegativeButton(context.getString(R.string.no), (dialog, which) -> {
+ dialog.dismiss();
+ }).show();
+ } else if (challenge != null) {
+ // Card tapped
EventBus.getDefault().post(new ShowChallengeTasksCommand(challenge.id));
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java
index bc0d336a8..50ef6c6ad 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.java
@@ -4,6 +4,7 @@ import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -55,7 +56,6 @@ public class ChallengeListFragment extends BaseMainFragment implements View.OnCl
super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_challengeslist, container, false);
unbinder = ButterKnife.bind(this, v);
- swipeRefreshLayout.setOnRefreshListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
recyclerView.setAdapter(challengeAdapter);
@@ -84,27 +84,14 @@ public class ChallengeListFragment extends BaseMainFragment implements View.OnCl
query = query.and(Condition.column("user_id").is(user.getId()));
}
- query.async().queryList(new TransactionListener>() {
- @Override
- public void onResultReceived(List result) {
- if (result.size() != 0) {
- setAdapterEntries(result);
- }
+ List challenges = query.queryList();
- // load online challenges & save to database
- onRefresh();
- }
+ if (challenges.size() != 0) {
+ setAdapterEntries(challenges);
+ }
- @Override
- public boolean onReady(BaseTransaction> transaction) {
- return false;
- }
-
- @Override
- public boolean hasResult(BaseTransaction> transaction, List result) {
- return result.size() != 0;
- }
- });
+ // load online challenges & save to database
+ onRefresh();
}
private void fetchOnlineChallenges() {
@@ -146,19 +133,26 @@ public class ChallengeListFragment extends BaseMainFragment implements View.OnCl
swipeRefreshLayout.setRefreshing(false);
}
}, throwable -> {
+ Log.e("ChallengeListFragment", "", throwable);
+
+ if (swipeRefreshLayout != null) {
+ swipeRefreshLayout.setRefreshing(false);
+ }
});
}
}
private void setAdapterEntries(List challenges) {
-
challengeAdapter.setChallenges(challenges);
-
}
@Override
public void onClick(View v) {
}
+
+ public void addItem(Challenge challenge) {
+ challengeAdapter.addChallange(challenge);
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java
index 4a4fc18fc..f6c3084d5 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.java
@@ -11,10 +11,15 @@ import android.view.ViewGroup;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.components.AppComponent;
+import com.habitrpg.android.habitica.events.commands.JoinChallengeCommand;
+import com.habitrpg.android.habitica.events.commands.LeaveChallengeCommand;
import com.habitrpg.android.habitica.events.commands.ShowChallengeTasksCommand;
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity;
-import com.habitrpg.android.habitica.ui.activities.FullProfileActivity;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
+import com.magicmicky.habitrpgwrapper.lib.models.Challenge;
+import com.raizlabs.android.dbflow.sql.language.Delete;
+import com.raizlabs.android.dbflow.sql.language.Select;
+import com.raizlabs.android.dbflow.sql.language.Update;
import org.greenrobot.eventbus.Subscribe;
@@ -30,7 +35,6 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
View v = inflater.inflate(R.layout.fragment_viewpager, container, false);
viewPager = (ViewPager) v.findViewById(R.id.view_pager);
- viewPager.setCurrentItem(1);
setViewPagerAdapter();
@@ -81,9 +85,9 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
- return "My Challenges";
+ return getString(R.string.my_challenges);
case 1:
- return "Public";
+ return getString(R.string.public_challenges);
}
return "";
}
@@ -105,4 +109,35 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
+
+ @Subscribe
+ public void onEvent(JoinChallengeCommand cmd){
+ this.apiHelper.apiService.joinChallenge(cmd.challengeId)
+ .compose(apiHelper.configureApiCallObserver())
+ .subscribe(challenge -> {
+ challenge.user_id = this.user.getId();
+
+ userChallengesFragment.addItem(challenge);
+ }, throwable -> {
+ });
+ }
+
+ @Subscribe
+ public void onEvent(LeaveChallengeCommand cmd){
+ this.apiHelper.apiService.leaveChallenge(cmd.challengeId)
+ .compose(apiHelper.configureApiCallObserver())
+ .subscribe(aVoid -> {
+
+ Challenge challenge = new Select().from(Challenge.class).byIds(cmd.challengeId).querySingle();
+ challenge.user_id = null;
+ challenge.save();
+
+ this.user.resetChallengeList();
+
+ userChallengesFragment.onRefresh();
+ availableChallengesFragment.onRefresh();
+ }, throwable -> {
+ });
+ }
+
}
diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java
index 13b9d9628..502264922 100644
--- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java
+++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java
@@ -261,6 +261,8 @@ public interface ApiService {
@DELETE("user/push-devices/{regId}")
Observable deletePushDevice(@Path("regId") String regId);
+ /* challenges api */
+
@GET("challenges/user")
Observable> getUserChallenges();
@@ -270,6 +272,12 @@ public interface ApiService {
@GET("challenges/{challengeId}")
Observable getChallenge(@Path("challengeId") String challengeId);
+ @POST("challenges/{challengeId}/join")
+ Observable joinChallenge(@Path("challengeId") String challengeId);
+
+ @POST("challenges/{challengeId}/leave")
+ Observable leaveChallenge(@Path("challengeId") String challengeId);
+
//DEBUG: These calls only work on a local development server
@POST("debug/add-ten-gems")
diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/HabitRPGUser.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/HabitRPGUser.java
index de69e4b6c..6410844ea 100644
--- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/HabitRPGUser.java
+++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/HabitRPGUser.java
@@ -126,6 +126,10 @@ public class HabitRPGUser extends BaseModel {
this.challengeList = challenges;
}
+ public void resetChallengeList(){
+ challengeList = null;
+ }
+
public Preferences getPreferences() {
return preferences;
}
diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/utils/ChallengeDeserializer.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/utils/ChallengeDeserializer.java
index a13de0a8e..a36937a5c 100644
--- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/utils/ChallengeDeserializer.java
+++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/utils/ChallengeDeserializer.java
@@ -40,6 +40,7 @@ public class ChallengeDeserializer implements JsonDeserializer {
if (profile != null) {
challenge.leaderName = profile.get("name").getAsString();
+ challenge.leaderId = leaderObj.get("id").getAsString();
}
}
}