Added feature: Vote in ViewPostDetailActivity. Fix some behavior after the vote fails.

This commit is contained in:
Alex Ning 2018-08-19 00:03:56 +08:00
parent 38344e305c
commit 23bf92d9cf
6 changed files with 250 additions and 21 deletions

View File

@ -28,10 +28,10 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0-beta01'
implementation 'com.android.support:design:28.0.0-beta01'
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support:design:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:support-v4:28.0.0-beta01'
implementation 'com.android.support:support-v4:28.0.0-rc01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
@ -39,9 +39,9 @@ dependencies {
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.google.android.exoplayer:exoplayer:2.7.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.0'
implementation 'com.android.support:customtabs:28.0.0-beta01'
implementation 'com.android.support:customtabs:28.0.0-rc01'
implementation 'com.alexvasilkov:gesture-views:2.5.2'
implementation 'com.android.support:cardview-v7:28.0.0-beta01'
implementation 'com.android.support:cardview-v7:28.0.0-rc01'
implementation 'com.github.bumptech.glide:glide:4.6.1'
implementation 'com.github.pwittchen:swipe-rx2:0.3.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
@ -52,4 +52,6 @@ dependencies {
// Lifecycle components
implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
}

View File

@ -2,6 +2,7 @@ package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.Intent;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.NonNull;
@ -299,6 +300,8 @@ class BestPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.View
@Override
public void onClick(View view) {
final boolean isDownvotedBefore = ((DataViewHolder) holder).downvoteButton.getColorFilter() != null;
final ColorFilter downvoteButtonColorFilter = ((DataViewHolder) holder).downvoteButton.getColorFilter();
((DataViewHolder) holder).downvoteButton.clearColorFilter();
if (((DataViewHolder) holder).upvoteButton.getColorFilter() == null) {
@ -325,7 +328,7 @@ class BestPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.View
Toast.makeText(mContext, "Cannot upvote this post", Toast.LENGTH_SHORT).show();
((DataViewHolder) holder).upvoteButton.clearColorFilter();
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore()));
((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
((DataViewHolder) holder).downvoteButton.setColorFilter(downvoteButtonColorFilter);
}
}, id, RedditUtils.DIR_UPVOTE, ((DataViewHolder) holder).getAdapterPosition(), 1);
} else {
@ -357,6 +360,7 @@ class BestPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.View
public void onClick(View view) {
final boolean isUpvotedBefore = ((DataViewHolder) holder).upvoteButton.getColorFilter() != null;
final ColorFilter upvoteButtonColorFilter = ((DataViewHolder) holder).upvoteButton.getColorFilter();
((DataViewHolder) holder).upvoteButton.clearColorFilter();
if (((DataViewHolder) holder).downvoteButton.getColorFilter() == null) {
((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
@ -382,7 +386,7 @@ class BestPostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.View
Toast.makeText(mContext, "Cannot downvote this post", Toast.LENGTH_SHORT).show();
((DataViewHolder) holder).downvoteButton.clearColorFilter();
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mBestPostData.get(position).getScore()));
((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
((DataViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter);
}
}, id, RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition(), 1);
} else {

View File

@ -224,7 +224,7 @@ public class MainActivity extends AppCompatActivity {
}, 1);
}
if(mInsertSuccess) {
if(!mInsertSuccess) {
new FetchSubscribedThing(this, Volley.newRequestQueue(this), new ArrayList<SubscribedSubredditData>(),
new ArrayList<SubscribedUserData>(), new ArrayList<SubredditData>())
.fetchSubscribedSubreddits(new FetchSubscribedThing.FetchSubscribedSubredditsListener() {

View File

@ -1,6 +1,7 @@
package ml.docilealligator.infinityforreddit;
import android.content.Intent;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
@ -8,6 +9,7 @@ import android.support.annotation.Nullable;
import android.support.customtabs.CustomTabsIntent;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.DividerItemDecoration;
@ -20,6 +22,7 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
@ -52,7 +55,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
private LinearLayout mNoCommentWrapperLinearLayout;
private ImageView mNoCommentImageView;
private RequestQueue mVoteThingQueue;
private RequestQueue mVoteThingRequestQueue;
private RequestQueue mAcquireAccessTokenRequestQueue;
private RequestQueue mCommentQueue;
@ -82,9 +85,9 @@ public class ViewPostDetailActivity extends AppCompatActivity {
ImageView imageView = findViewById(R.id.image_view_view_post_detail);
ImageView noPreviewLinkImageView = findViewById(R.id.image_view_no_preview_link_view_post_detail);
ImageView plusButton = findViewById(R.id.plus_button_view_post_detail);
TextView scoreTextView = findViewById(R.id.score_text_view_view_post_detail);
ImageView minusButton = findViewById(R.id.minus_button_view_post_detail);
final ImageView upvoteButton = findViewById(R.id.plus_button_view_post_detail);
final TextView scoreTextView = findViewById(R.id.score_text_view_view_post_detail);
final ImageView downvoteButton = findViewById(R.id.minus_button_view_post_detail);
ImageView shareButton = findViewById(R.id.share_button_view_post_detail);
mCommentProgressbar = findViewById(R.id.comment_progress_bar_view_post_detail);
@ -104,10 +107,21 @@ public class ViewPostDetailActivity extends AppCompatActivity {
Glide.with(this).load(R.drawable.subreddit_default_icon).into(subredditIconCircleImageView);
}
switch (mPostData.getVoteType()) {
case 1:
//Upvote
upvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
break;
case -1:
//Downvote
downvoteButton.setColorFilter(ContextCompat.getColor(this, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
break;
}
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
mVoteThingQueue = Volley.newRequestQueue(this);
mVoteThingRequestQueue = Volley.newRequestQueue(this);
mAcquireAccessTokenRequestQueue = Volley.newRequestQueue(this);
mCommentQueue = Volley.newRequestQueue(this);
@ -284,6 +298,160 @@ public class ViewPostDetailActivity extends AppCompatActivity {
}
}
queryComment();
/*final Observable<Integer> observable = Observable.create(
new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(mPostData.getVoteType());
emitter.onComplete();
Log.i("asdasdf", "adasdfasdf");
Toast.makeText(ViewPostDetailActivity.this, "observable", Toast.LENGTH_SHORT).show();
}
}
);
final Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Toast.makeText(ViewPostDetailActivity.this, "complete", Toast.LENGTH_SHORT).show();
}
};*/
upvoteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//observable.subscribe(observer);
final boolean isDownvotedBefore = downvoteButton.getColorFilter() != null;
final ColorFilter downVoteButtonColorFilter = downvoteButton.getColorFilter();
downvoteButton.clearColorFilter();
if (upvoteButton.getColorFilter() == null) {
upvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
if(isDownvotedBefore) {
scoreTextView.setText(Integer.toString(mPostData.getScore() + 2));
} else {
scoreTextView.setText(Integer.toString(mPostData.getScore() + 1));
}
new VoteThing(ViewPostDetailActivity.this, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(1);
if(isDownvotedBefore) {
mPostData.setScore(mPostData.getScore() + 2);
} else {
mPostData.setScore(mPostData.getScore() + 1);
}
}
@Override
public void onVoteThingFail() {
Toast.makeText(ViewPostDetailActivity.this, "Cannot upvote this post", Toast.LENGTH_SHORT).show();
upvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore()));
downvoteButton.setColorFilter(downVoteButtonColorFilter);
}
}, mPostData.getFullName(), RedditUtils.DIR_UPVOTE, 1);
} else {
//Upvoted before
upvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore() - 1));
new VoteThing(ViewPostDetailActivity.this, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(0);
mPostData.setScore(mPostData.getScore() - 1);
}
@Override
public void onVoteThingFail() {
Toast.makeText(ViewPostDetailActivity.this, "Cannot unvote this post", Toast.LENGTH_SHORT).show();
scoreTextView.setText(Integer.toString(mPostData.getScore() + 1));
upvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
mPostData.setScore(mPostData.getScore() + 1);
}
}, mPostData.getFullName(), RedditUtils.DIR_UNVOTE, 1);
}
}
});
downvoteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//observable.subscribe(observer);
final boolean isUpvotedBefore = upvoteButton.getColorFilter() != null;
final ColorFilter upvoteButtonColorFilter = upvoteButton.getColorFilter();
upvoteButton.clearColorFilter();
if (downvoteButton.getColorFilter() == null) {
downvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
if (isUpvotedBefore) {
scoreTextView.setText(Integer.toString(mPostData.getScore() - 2));
} else {
scoreTextView.setText(Integer.toString(mPostData.getScore() - 1));
}
new VoteThing(ViewPostDetailActivity.this, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(-1);
if(isUpvotedBefore) {
mPostData.setScore(mPostData.getScore() - 2);
} else {
mPostData.setScore(mPostData.getScore() - 1);
}
}
@Override
public void onVoteThingFail() {
Toast.makeText(ViewPostDetailActivity.this, "Cannot downvote this post", Toast.LENGTH_SHORT).show();
downvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore()));
upvoteButton.setColorFilter(upvoteButtonColorFilter);
}
}, mPostData.getFullName(), RedditUtils.DIR_DOWNVOTE, 1);
} else {
//Down voted before
downvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore() + 1));
new VoteThing(ViewPostDetailActivity.this, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue).votePost(new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(0);
mPostData.setScore(mPostData.getScore());
}
@Override
public void onVoteThingFail() {
Toast.makeText(ViewPostDetailActivity.this, "Cannot unvote this post", Toast.LENGTH_SHORT).show();
downvoteButton.setColorFilter(ContextCompat.getColor(ViewPostDetailActivity.this, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
scoreTextView.setText(Integer.toString(mPostData.getScore()));
mPostData.setScore(mPostData.getScore());
}
}, mPostData.getFullName(), RedditUtils.DIR_UNVOTE, 1);
}
}
});
}
private void queryComment() {
@ -299,7 +467,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
mMoreCommentCount = moreCommentCount;
if(commentData.size() > 0) {
CommentRecyclerViewAdapter adapter = new CommentRecyclerViewAdapter(
ViewPostDetailActivity.this, commentData, mVoteThingQueue, mAcquireAccessTokenRequestQueue);
ViewPostDetailActivity.this, commentData, mVoteThingRequestQueue, mAcquireAccessTokenRequestQueue);
mRecyclerView.setAdapter(adapter);
mCommentCardView.setVisibility(View.VISIBLE);
} else {

View File

@ -23,8 +23,12 @@ class VoteThing {
void onVoteThingFail(int position);
}
interface VoteThingWithoutPositionListener {
void onVoteThingSuccess();
void onVoteThingFail();
}
private Context mContext;
private VoteThingListener mVoteThingListener;
private RequestQueue mQueue;
private RequestQueue mAcquireAccessTokenRequestQueue;
@ -34,17 +38,17 @@ class VoteThing {
mAcquireAccessTokenRequestQueue = acquireAccessTokenRequestQueue;
}
void votePost(VoteThingListener voteThingListener, final String fullName, final String point, final int position, final int refreshTime) {
void votePost(final VoteThingListener voteThingListener, final String fullName, final String point, final int position, final int refreshTime) {
if(mContext != null) {
if(refreshTime < 0) {
mVoteThingListener.onVoteThingFail(position);
voteThingListener.onVoteThingFail(position);
return;
}
mVoteThingListener = voteThingListener;
StringRequest voteRequest = new StringRequest(Request.Method.POST, RedditUtils.OAUTH_API_BASE_URI + RedditUtils.VOTE_SUFFIX, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mVoteThingListener.onVoteThingSuccess(position);
voteThingListener.onVoteThingSuccess(position);
}
}, new Response.ErrorListener() {
@Override
@ -55,14 +59,65 @@ class VoteThing {
new AcquireAccessToken.AcquireAccessTokenListener() {
@Override
public void onAcquireAccessTokenSuccess() {
votePost(mVoteThingListener, fullName, point, position, refreshTime - 1);
votePost(voteThingListener, fullName, point, position, refreshTime - 1);
}
@Override
public void onAcquireAccessTokenFail() {}
});
} else {
mVoteThingListener.onVoteThingFail(position);
voteThingListener.onVoteThingFail(position);
}
}
}) {
@Override
protected Map<String, String> getParams() {
HashMap<String, String> params = new HashMap<>();
params.put(RedditUtils.DIR_KEY, point);
params.put(RedditUtils.ID_KEY, fullName);
params.put(RedditUtils.RANK_KEY, RedditUtils.RANK);
return params;
}
@Override
public Map<String, String> getHeaders() {
String accessToken = mContext.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
return RedditUtils.getOAuthHeader(accessToken);
}
};
voteRequest.setTag(VoteThing.class);
mQueue.add(voteRequest);
}
}
void votePost(final VoteThingWithoutPositionListener voteThingWithoutPositionListener, final String fullName, final String point, final int refreshTime) {
if(mContext != null) {
if(refreshTime < 0) {
voteThingWithoutPositionListener.onVoteThingFail();
return;
}
StringRequest voteRequest = new StringRequest(Request.Method.POST, RedditUtils.OAUTH_API_BASE_URI + RedditUtils.VOTE_SUFFIX, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
voteThingWithoutPositionListener.onVoteThingSuccess();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error instanceof AuthFailureError) {
//Access token expired
new AcquireAccessToken(mContext).refreshAccessToken(mAcquireAccessTokenRequestQueue,
new AcquireAccessToken.AcquireAccessTokenListener() {
@Override
public void onAcquireAccessTokenSuccess() {
votePost(voteThingWithoutPositionListener, fullName, point, refreshTime - 1);
}
@Override
public void onAcquireAccessTokenFail() {}
});
} else {
voteThingWithoutPositionListener.onVoteThingFail();
}
}
}) {