diff --git a/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServices.java b/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServices.java
index 7c73bdde5..24361017c 100644
--- a/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServices.java
+++ b/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServices.java
@@ -46,6 +46,8 @@ public Exception(int message) {
boolean voteUp(Context context, String itemId, Callback callback);
+ boolean voteDown(Context context, String itemId, Callback callback);
+
void reply(Context context, String parentId, String text, Callback callback);
void submit(Context context, String title, String content, boolean isUrl, Callback callback);
diff --git a/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServicesClient.java b/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServicesClient.java
index 3a68730ba..b90732f8a 100644
--- a/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServicesClient.java
+++ b/app/src/main/java/io/github/hidroh/materialistic/accounts/UserServicesClient.java
@@ -63,6 +63,7 @@ public class UserServicesClient implements UserServices {
private static final String SUBMIT_PARAM_FNID = "fnid";
private static final String SUBMIT_PARAM_FNOP = "fnop";
private static final String VOTE_DIR_UP = "up";
+ private static final String VOTE_DIR_DOWN = "down";
private static final String DEFAULT_REDIRECT = "news";
private static final String CREATING_TRUE = "t";
private static final String DEFAULT_FNOP = "submit-page";
@@ -102,7 +103,21 @@ public boolean voteUp(Context context, String itemId, Callback callback) {
return false;
}
Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show();
- execute(postVote(credentials.first, credentials.second, itemId))
+ execute(postVoteUp(credentials.first, credentials.second, itemId))
+ .map(response -> response.code() == HttpURLConnection.HTTP_MOVED_TEMP)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(callback::onDone, callback::onError);
+ return true;
+ }
+
+ @Override
+ public boolean voteDown(Context context, String itemId, Callback callback) {
+ Pair credentials = AppUtils.getCredentials(context);
+ if (credentials == null) {
+ return false;
+ }
+ Toast.makeText(context, R.string.sending, Toast.LENGTH_SHORT).show();
+ execute(postVoteDown(credentials.first, credentials.second, itemId))
.map(response -> response.code() == HttpURLConnection.HTTP_MOVED_TEMP)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(callback::onDone, callback::onError);
@@ -190,7 +205,15 @@ private Request postLogin(String username, String password, boolean createAccoun
.build();
}
- private Request postVote(String username, String password, String itemId) {
+ private Request postVoteUp(String username, String password, String itemId) {
+ return postVote(username, password, itemId, VOTE_DIR_UP);
+ }
+
+ private Request postVoteDown(String username, String password, String itemId) {
+ return postVote(username, password, itemId, VOTE_DIR_DOWN);
+ }
+
+ private Request postVote(String username, String password, String itemId, String upOrDown) {
return new Request.Builder()
.url(HttpUrl.parse(BASE_WEB_URL)
.newBuilder()
@@ -200,11 +223,12 @@ private Request postVote(String username, String password, String itemId) {
.add(LOGIN_PARAM_ACCT, username)
.add(LOGIN_PARAM_PW, password)
.add(VOTE_PARAM_ID, itemId)
- .add(VOTE_PARAM_HOW, VOTE_DIR_UP)
+ .add(VOTE_PARAM_HOW, upOrDown)
.build())
.build();
}
+
private Request postReply(String parentId, String text, String username, String password) {
return new Request.Builder()
.url(HttpUrl.parse(BASE_WEB_URL)
diff --git a/app/src/main/java/io/github/hidroh/materialistic/widget/FavoriteRecyclerViewAdapter.java b/app/src/main/java/io/github/hidroh/materialistic/widget/FavoriteRecyclerViewAdapter.java
index 9d3f4f2ae..9cef9f248 100644
--- a/app/src/main/java/io/github/hidroh/materialistic/widget/FavoriteRecyclerViewAdapter.java
+++ b/app/src/main/java/io/github/hidroh/materialistic/widget/FavoriteRecyclerViewAdapter.java
@@ -273,7 +273,7 @@ private void showMoreOptions(View v, final Favorite item) {
mPopupMenu.create(mContext, v, Gravity.NO_GRAVITY)
.inflate(R.menu.menu_contextual_favorite)
.setOnMenuItemClickListener(menuItem -> {
- if (menuItem.getItemId() == R.id.menu_contextual_vote) {
+ if (menuItem.getItemId() == R.id.menu_contextual_vote_up) {
vote(item);
return true;
}
diff --git a/app/src/main/java/io/github/hidroh/materialistic/widget/ItemRecyclerViewAdapter.java b/app/src/main/java/io/github/hidroh/materialistic/widget/ItemRecyclerViewAdapter.java
index 08f9231ba..c60a901a2 100644
--- a/app/src/main/java/io/github/hidroh/materialistic/widget/ItemRecyclerViewAdapter.java
+++ b/app/src/main/java/io/github/hidroh/materialistic/widget/ItemRecyclerViewAdapter.java
@@ -234,8 +234,12 @@ private void bindActions(final VH holder, final Item item) {
mPopupMenu.create(mContext, holder.mMoreButton, Gravity.NO_GRAVITY)
.inflate(R.menu.menu_contextual_comment)
.setOnMenuItemClickListener(menuItem -> {
- if (menuItem.getItemId() == R.id.menu_contextual_vote) {
- vote(item);
+ if (menuItem.getItemId() == R.id.menu_contextual_vote_up) {
+ voteUp(item);
+ return true;
+ }
+ if (menuItem.getItemId() == R.id.menu_contextual_vote_down) {
+ voteDown(item);
return true;
}
if (menuItem.getItemId() == R.id.menu_contextual_comment) {
@@ -257,10 +261,14 @@ private void bindActions(final VH holder, final Item item) {
.show());
}
- private void vote(final Item item) {
+ private void voteUp(final Item item) {
mUserServices.voteUp(mContext, item.getId(), new VoteCallback(this));
}
+ private void voteDown(final Item item) {
+ mUserServices.voteDown(mContext, item.getId(), new VoteCallback(this));
+ }
+
@Synthetic
void onVoted(Boolean successful) {
if (successful == null) {
diff --git a/app/src/main/java/io/github/hidroh/materialistic/widget/StoryRecyclerViewAdapter.java b/app/src/main/java/io/github/hidroh/materialistic/widget/StoryRecyclerViewAdapter.java
index 3db6e995f..bfdfbabec 100644
--- a/app/src/main/java/io/github/hidroh/materialistic/widget/StoryRecyclerViewAdapter.java
+++ b/app/src/main/java/io/github/hidroh/materialistic/widget/StoryRecyclerViewAdapter.java
@@ -442,7 +442,7 @@ void showMoreOptions(View v, final Item story, final ItemViewHolder holder) {
story.isFavorite() ? R.string.unsave : R.string.save)
.setMenuItemVisible(R.id.menu_contextual_save,
!mCallback.hasAction(Preferences.SwipeAction.Save))
- .setMenuItemVisible(R.id.menu_contextual_vote,
+ .setMenuItemVisible(R.id.menu_contextual_vote_up,
!mCallback.hasAction(Preferences.SwipeAction.Vote))
.setMenuItemVisible(R.id.menu_contextual_refresh,
!mCallback.hasAction(Preferences.SwipeAction.Refresh))
@@ -451,7 +451,7 @@ void showMoreOptions(View v, final Item story, final ItemViewHolder holder) {
toggleSave(story);
return true;
}
- if (item.getItemId() == R.id.menu_contextual_vote) {
+ if (item.getItemId() == R.id.menu_contextual_vote_up) {
vote(story, holder);
return true;
}
diff --git a/app/src/main/res/menu/menu_contextual_comment.xml b/app/src/main/res/menu/menu_contextual_comment.xml
index d4a08be98..a618c4336 100644
--- a/app/src/main/res/menu/menu_contextual_comment.xml
+++ b/app/src/main/res/menu/menu_contextual_comment.xml
@@ -17,8 +17,11 @@
Vuelve a escribir tu contraseña
Votar arriba
+ Votar abajo
Votada correctamente
Ha sido imposible contabilizar tu voto. Intentalo de nuevo por favor.
Enviando…
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
index 75d0cc82e..46a976bae 100644
--- a/app/src/main/res/values/ids.xml
+++ b/app/src/main/res/values/ids.xml
@@ -84,7 +84,8 @@
-
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 33b07e4c5..e84e782ba 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -238,6 +238,7 @@
Unsave
Re-enter your password
Vote up
+ Vote down
Successfully voted
Fail to record vote. Please try again.
Sending...
diff --git a/app/src/test/java/io/github/hidroh/materialistic/FavoriteActivityTest.java b/app/src/test/java/io/github/hidroh/materialistic/FavoriteActivityTest.java
index 9e401941c..d3d23d7f2 100644
--- a/app/src/test/java/io/github/hidroh/materialistic/FavoriteActivityTest.java
+++ b/app/src/test/java/io/github/hidroh/materialistic/FavoriteActivityTest.java
@@ -302,7 +302,7 @@ public void testVoteItem() {
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
Assert.assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
- .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
+ .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote_up));
verify(userServices).voteUp(any(Context.class), any(), userServicesCallback.capture());
userServicesCallback.getValue().onDone(true);
assertEquals(activity.getString(R.string.voted), ShadowToast.getTextOfLatestToast());
@@ -315,7 +315,7 @@ public void testVoteItemPromptToLogin() {
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
Assert.assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
- .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
+ .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote_up));
verify(userServices).voteUp(any(Context.class), any(), userServicesCallback.capture());
userServicesCallback.getValue().onDone(false);
assertThat(shadowOf(activity).getNextStartedActivity())
@@ -329,7 +329,7 @@ public void testVoteItemFailed() {
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
Assert.assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
- .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
+ .onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote_up));
verify(userServices).voteUp(any(Context.class), any(), userServicesCallback.capture());
userServicesCallback.getValue().onError(new IOException());
assertEquals(activity.getString(R.string.vote_failed), ShadowToast.getTextOfLatestToast());