Use OkHttp3 Authenticator instead of OkHttp Interceptor to handle the case when the request fails with code 401. Refresh the access token in a synchronized block to avoid getting more than one access tokens and getting duplicate posts when performing multiple unauthorized requests. Minor bugs fixed.

This commit is contained in:
Alex Ning 2018-10-14 11:24:38 +08:00
parent 8b52810d7c
commit 4d0a0725c9
15 changed files with 220 additions and 335 deletions

View File

@ -0,0 +1,43 @@
package ml.docilealligator.infinityforreddit;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.io.IOException;
import okhttp3.Authenticator;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
class AccessTokenAuthenticator implements Authenticator {
private SharedPreferences mAuthInfoSharedPreferences;
AccessTokenAuthenticator(SharedPreferences authInfoSharedPreferences) {
mAuthInfoSharedPreferences = authInfoSharedPreferences;
}
@Nullable
@Override
public Request authenticate(@NonNull Route route, @NonNull Response response) throws IOException {
if (response.code() == 401) {
String accessToken = response.request().header(RedditUtils.AUTHORIZATION_KEY).substring(RedditUtils.AUTHORIZATION_BASE.length());
synchronized (this) {
String accessTokenFromSharedPreferences = mAuthInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
if (accessToken.equals(accessTokenFromSharedPreferences)) {
String newAccessToken = RefreshAccessToken.refreshAccessToken(mAuthInfoSharedPreferences);
if (!newAccessToken.equals("")) {
return response.request().newBuilder().headers(Headers.of(RedditUtils.getOAuthHeader(newAccessToken))).build();
} else {
return null;
}
} else {
return response.request().newBuilder().headers(Headers.of(RedditUtils.getOAuthHeader(accessTokenFromSharedPreferences))).build();
}
}
}
return null;
}
}

View File

@ -1,6 +1,7 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.ColorFilter;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
@ -29,19 +30,22 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
private Context mContext;
private Retrofit mRetrofit;
private Retrofit mOauthRetrofit;
private SharedPreferences mSharedPreferences;
private ArrayList<CommentData> mCommentData;
private MultiLevelRecyclerView mMultiLevelRecyclerView;
private String subredditNamePrefixed;
private String article;
private Locale locale;
CommentMultiLevelRecyclerViewAdapter(Context context, Retrofit retrofit, Retrofit oauthRetrofit, ArrayList<CommentData> commentData,
CommentMultiLevelRecyclerViewAdapter(Context context, Retrofit retrofit, Retrofit oauthRetrofit,
SharedPreferences sharedPreferences, ArrayList<CommentData> commentData,
MultiLevelRecyclerView multiLevelRecyclerView,
String subredditNamePrefixed, String article, Locale locale) {
super(commentData);
mContext = context;
mRetrofit = retrofit;
mOauthRetrofit = oauthRetrofit;
mSharedPreferences = sharedPreferences;
mCommentData = commentData;
mMultiLevelRecyclerView = multiLevelRecyclerView;
this.subredditNamePrefixed = subredditNamePrefixed;
@ -136,7 +140,7 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 1));
}
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit,mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
commentItem.setVoteType(1);
@ -154,13 +158,13 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore()));
((CommentViewHolder) holder).downvoteButton.setColorFilter(minusButtonColorFilter);
}
}, commentItem.getFullName(), RedditUtils.DIR_UPVOTE, ((CommentViewHolder) holder).getAdapterPosition(), 1);
}, commentItem.getFullName(), RedditUtils.DIR_UPVOTE, ((CommentViewHolder) holder).getAdapterPosition());
} else {
//Upvoted before
((CommentViewHolder) holder).upvoteButton.clearColorFilter();
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() - 1));
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
commentItem.setVoteType(0);
@ -174,7 +178,7 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
commentItem.setScore(commentItem.getScore() + 1);
}
}, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, ((CommentViewHolder) holder).getAdapterPosition(), 1);
}, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, ((CommentViewHolder) holder).getAdapterPosition());
}
}
});
@ -195,7 +199,7 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() - 1));
}
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
commentItem.setVoteType(-1);
@ -213,13 +217,13 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore()));
((CommentViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter);
}
}, commentItem.getFullName(), RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition(), 1);
}, commentItem.getFullName(), RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition());
} else {
//Down voted before
((CommentViewHolder) holder).downvoteButton.clearColorFilter();
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore() + 1));
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
commentItem.setVoteType(0);
@ -233,7 +237,7 @@ class CommentMultiLevelRecyclerViewAdapter extends MultiLevelAdapter {
((CommentViewHolder) holder).scoreTextView.setText(Integer.toString(commentItem.getScore()));
commentItem.setScore(commentItem.getScore());
}
}, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, holder.getAdapterPosition(), 1);
}, commentItem.getFullName(), RedditUtils.DIR_UNVOTE, holder.getAdapterPosition());
}
}
});

View File

@ -1,6 +1,6 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
@ -19,20 +19,15 @@ class FetchSubscribedThing {
void onFetchSubscribedThingFail();
}
static void fetchSubscribedThing(final Context context, final Retrofit retrofit, final String lastItem,
static void fetchSubscribedThing(final Retrofit retrofit, final SharedPreferences sharedPreferences,
final String lastItem,
final ArrayList<SubscribedSubredditData> subscribedSubredditData,
final ArrayList<SubscribedUserData> subscribedUserData,
final ArrayList<SubredditData> subredditData,
final FetchSubscribedThingListener fetchSubscribedThingListener, final int refreshTime) {
if(refreshTime < 0) {
fetchSubscribedThingListener.onFetchSubscribedThingFail();
return;
}
final FetchSubscribedThingListener fetchSubscribedThingListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
String accessToken = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
String accessToken = sharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
Call<String> subredditDataCall = api.getSubscribedThing(lastItem, RedditUtils.getOAuthHeader(accessToken));
subredditDataCall.enqueue(new Callback<String>() {
@ -52,9 +47,9 @@ class FetchSubscribedThing {
fetchSubscribedThingListener.onFetchSubscribedThingSuccess(
subscribedSubredditData, subscribedUserData, subredditData);
} else {
fetchSubscribedThing(context, retrofit, lastItem, subscribedSubredditData,
fetchSubscribedThing(retrofit, sharedPreferences, lastItem, subscribedSubredditData,
subscribedUserData, subredditData,
fetchSubscribedThingListener, refreshTime);
fetchSubscribedThingListener);
}
}
@ -63,17 +58,6 @@ class FetchSubscribedThing {
fetchSubscribedThingListener.onFetchSubscribedThingFail();
}
});
} else if(response.code() == 401) {
RefreshAccessToken.refreshAccessToken(context, new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
fetchSubscribedThing(context, retrofit, lastItem, subscribedSubredditData,
subscribedUserData, subredditData, fetchSubscribedThingListener, refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {}
});
} else {
Log.i("call failed", response.message());
fetchSubscribedThingListener.onFetchSubscribedThingFail();

View File

@ -1,6 +1,6 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
@ -15,32 +15,17 @@ class FetchUserInfo {
void onFetchUserInfoFail();
}
static void fetchUserInfo(final Retrofit retrofit, final Context context, final FetchUserInfoListener fetchUserInfoListener, final int refreshTime) {
if(refreshTime < 0) {
fetchUserInfoListener.onFetchUserInfoFail();
return;
}
static void fetchUserInfo(final Retrofit retrofit, SharedPreferences authInfoSharedPreferences,
final FetchUserInfoListener fetchUserInfoListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
String accessToken = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
Call<String> userInfo = api.getUserInfo(RedditUtils.getOAuthHeader(accessToken));
userInfo.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if(response.isSuccessful()) {
fetchUserInfoListener.onFetchUserInfoSuccess(response.body());
} else if(response.code() == 401){
RefreshAccessToken.refreshAccessToken(context, new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
fetchUserInfo(retrofit, context, fetchUserInfoListener, refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {}
});
} else {
Log.i("call failed", response.message());
fetchUserInfoListener.onFetchUserInfoFail();

View File

@ -9,7 +9,9 @@ public class Infinity extends Application {
public void onCreate() {
super.onCreate();
mNetworkComponent = DaggerNetworkComponent.create();
mNetworkComponent = DaggerNetworkComponent.builder()
.networkModule(new NetworkModule(this))
.build();
}
public NetworkComponent getmNetworkComponent() {

View File

@ -26,7 +26,6 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
@ -65,8 +64,13 @@ public class MainActivity extends AppCompatActivity {
private SubscribedSubredditViewModel mSubscribedSubredditViewModel;
private SubscribedUserViewModel mSubscribedUserViewModel;
@Inject
@Named("oauth")
@Inject @Named("user_info")
SharedPreferences mUserInfoSharedPreferences;
@Inject @Named("auth_info")
SharedPreferences mAuthInfoSharedPreferences;
@Inject @Named("oauth")
Retrofit mOauthRetrofit;
@Override
@ -101,28 +105,7 @@ public class MainActivity extends AppCompatActivity {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_content_main, mFragment).commit();
}
Calendar now = Calendar.getInstance();
Calendar queryAccessTokenTime = Calendar.getInstance();
queryAccessTokenTime.setTimeInMillis(getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getLong(SharedPreferencesUtils.QUERY_ACCESS_TOKEN_TIME_KEY, 0));
int interval = getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getInt(SharedPreferencesUtils.ACCESS_TOKEN_EXPIRE_INTERVAL_KEY, 0);
queryAccessTokenTime.add(Calendar.SECOND, interval - 300);
if(now.after(queryAccessTokenTime)) {
RefreshAccessToken.refreshAccessToken(this,
new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
loadUserData(savedInstanceState);
}
@Override
public void onRefreshAccessTokenFail() {}
});
} else {
loadUserData(savedInstanceState);
}
loadUserData(savedInstanceState);
View header = findViewById(R.id.nav_header_main_activity);
mNameTextView = header.findViewById(R.id.name_text_view_nav_header_main);
@ -191,7 +174,7 @@ public class MainActivity extends AppCompatActivity {
private void loadUserData(Bundle savedInstanceState) {
if (savedInstanceState == null) {
if (!mFetchUserInfoSuccess) {
FetchUserInfo.fetchUserInfo(mOauthRetrofit, this, new FetchUserInfo.FetchUserInfoListener() {
FetchUserInfo.fetchUserInfo(mOauthRetrofit, mAuthInfoSharedPreferences, new FetchUserInfo.FetchUserInfoListener() {
@Override
public void onFetchUserInfoSuccess(String response) {
ParseUserInfo.parseUserInfo(response, new ParseUserInfo.ParseUserInfoListener() {
@ -212,7 +195,7 @@ public class MainActivity extends AppCompatActivity {
mKarmaTextView.setText(mKarma);
SharedPreferences.Editor editor = getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE).edit();
SharedPreferences.Editor editor = mUserInfoSharedPreferences.edit();
editor.putString(SharedPreferencesUtils.USER_KEY, name);
editor.putString(SharedPreferencesUtils.PROFILE_IMAGE_URL_KEY, profileImageUrl);
editor.putString(SharedPreferencesUtils.BANNER_IMAGE_URL_KEY, bannerImageUrl);
@ -232,11 +215,11 @@ public class MainActivity extends AppCompatActivity {
public void onFetchUserInfoFail() {
mFetchUserInfoSuccess = false;
}
}, 1);
});
}
if (!mInsertSuccess) {
FetchSubscribedThing.fetchSubscribedThing(this, mOauthRetrofit, null,
FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAuthInfoSharedPreferences, null,
new ArrayList<SubscribedSubredditData>(), new ArrayList<SubscribedUserData>(),
new ArrayList<SubredditData>(),
new FetchSubscribedThing.FetchSubscribedThingListener() {
@ -263,7 +246,7 @@ public class MainActivity extends AppCompatActivity {
public void onFetchSubscribedThingFail() {
mInsertSuccess = false;
}
}, 1);
});
}
}
}

View File

@ -1,5 +1,9 @@
package ml.docilealligator.infinityforreddit;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import javax.inject.Named;
import javax.inject.Singleton;
@ -11,11 +15,18 @@ import retrofit2.converter.scalars.ScalarsConverterFactory;
@Module
class NetworkModule {
Application mApplication;
public NetworkModule(Application application) {
mApplication = application;
}
@Provides @Named("oauth")
@Singleton
Retrofit provideOauthRetrofit() {
Retrofit provideOauthRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl(RedditUtils.OAUTH_API_BASE_URI)
.client(okHttpClient)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
}
@ -31,9 +42,20 @@ class NetworkModule {
@Provides
@Singleton
OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new OkHttpInterceptor());
return okHttpClient;
OkHttpClient provideOkHttpClient(@Named("auth_info") SharedPreferences sharedPreferences) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.authenticator(new AccessTokenAuthenticator(sharedPreferences));
return okHttpClientBuilder.build();
}
@Provides @Named("auth_info")
@Singleton
SharedPreferences provideAuthInfoSharedPreferences() {
return mApplication.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE);
}
@Provides @Named("user_info")
SharedPreferences provideUserInfoSharedPreferences() {
return mApplication.getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE);
}
}

View File

@ -1,48 +0,0 @@
package ml.docilealligator.infinityforreddit;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
class OkHttpInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
/*Request request = chain.request();
//Build new request
Request.Builder builder = request.newBuilder();
builder.header("Accept", "application/json"); //if necessary, say to consume JSON
String token = settings.getAccessToken(); //save token of this request for future
setAuthHeader(builder, token); //write current token to request
request = builder.build(); //overwrite old request
Response response = chain.proceed(request); //perform request, here original request will be executed
if (response.code() == 401) { //if unauthorized
synchronized (this) { //perform all 401 in sync blocks, to avoid multiply token updates
String currentToken = settings.getAccessToken(); //get currently stored token
if(currentToken != null && currentToken.equals(token)) { //compare current token with token that was stored before, if it was not updated - do update
int code = refreshToken() / 100; //refresh token
if(code != 2) { //if refresh token failed for some reason
if(code == 4) //only if response is 400, 500 might mean that token was not updated
logout(); //go to login screen
return response; //if token refresh failed - show error to user
}
}
if(settings.getAccessToken() != null) { //retry requires new auth token,
setAuthHeader(builder, settings.getAccessToken()); //set auth token to updated
request = builder.build();
return chain.proceed(request); //repeat request with new token
}
}
}
return response;*/
return null;
}
}

View File

@ -4,6 +4,7 @@ package ml.docilealligator.infinityforreddit;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
@ -58,15 +59,15 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
private boolean mIsBestPost;
private String mSubredditName;
@Inject
@Named("no_oauth")
@Inject @Named("no_oauth")
Retrofit mRetrofit;
@Inject
@Named("oauth")
@Inject @Named("oauth")
Retrofit mOauthRetrofit;
@Inject
@Inject @Named("auth_info")
SharedPreferences mSharedPreferences;
public PostFragment() {
// Required empty public constructor
}
@ -122,7 +123,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
@Override
public void onClick(View view) {
if(mIsBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost();
}
@ -142,7 +143,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
mPaginationSynchronizer.setLoadSuccess(savedInstanceState.getBoolean(LOAD_SUCCESS_STATE));
mPaginationSynchronizer.setLoadingState(savedInstanceState.getBoolean(LOADING_STATE_STATE));
PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), mOauthRetrofit,
mPostData, mPaginationSynchronizer, mIsBestPost);
mSharedPreferences, mPostData, mPaginationSynchronizer, mIsBestPost);
mPostRecyclerView.setAdapter(adapter);
if(mIsBestPost) {
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
@ -167,7 +168,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
});
if(mIsBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost();
}
@ -176,12 +177,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
return rootView;
}
private void fetchBestPost(final int refreshTime) {
if(refreshTime < 0) {
showErrorView();
return;
}
Log.i("fetch best post", "start" + refreshTime);
private void fetchBestPost() {
mFetchPostErrorLinearLayout.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
@ -212,7 +208,9 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if(isAdded() && getActivity() != null) {
mPostData = postData;
mLastItem = lastItem;
PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), mOauthRetrofit, postData, mPaginationSynchronizer, mIsBestPost);
PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(
getActivity(), mOauthRetrofit, mSharedPreferences,
postData, mPaginationSynchronizer, mIsBestPost);
mPostRecyclerView.setAdapter(adapter);
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
@ -230,19 +228,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
showErrorView();
}
});
} else if(response.code() == 401) {
// Error indicating that there was an Authentication Failure while performing the request
// Access token expired
RefreshAccessToken.refreshAccessToken(getActivity(),
new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
fetchBestPost(refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {}
});
} else {
Log.i("Post fetch error", response.message());
showErrorView();
@ -284,7 +269,9 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
if(isAdded() && getActivity() != null) {
mPostData = postData;
mLastItem = lastItem;
PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(getActivity(), mRetrofit, postData, mPaginationSynchronizer, mIsBestPost);
PostRecyclerViewAdapter adapter = new PostRecyclerViewAdapter(
getActivity(), mRetrofit, mSharedPreferences,
postData, mPaginationSynchronizer, mIsBestPost);
mPostRecyclerView.setAdapter(adapter);
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
@ -329,7 +316,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
@Override
public void onClick(View view) {
if (mIsBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost();
}
@ -358,7 +345,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
(mPostRecyclerView.getAdapter()).notifyDataSetChanged();
}
if(mIsBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost();
}

View File

@ -57,7 +57,7 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener {
@Override
public void retry() {
if (isBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost(subredditName, 1);
}
@ -78,7 +78,7 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener {
if((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) {
if(isBestPost) {
fetchBestPost(1);
fetchBestPost();
} else {
fetchPost(mSubredditName, 1);
}
@ -87,12 +87,7 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener {
}
private void fetchBestPost(final int refreshTime) {
if(refreshTime < 0) {
loadFailed();
return;
}
Log.i("fetch best post pag", "start");
private void fetchBestPost() {
isLoading = true;
loadSuccess = false;
mPaginationSynchronizer.setLoadingState(true);
@ -136,19 +131,6 @@ class PostPaginationScrollListener extends RecyclerView.OnScrollListener {
loadFailed();
}
});
} else if(response.code() == 401) {
//Access token expired
RefreshAccessToken.refreshAccessToken(mContext,
new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
fetchBestPost(refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {
}
});
} else {
Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show();
Log.i("best post", response.message());

View File

@ -2,6 +2,7 @@ package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@ -46,6 +47,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
private ArrayList<PostData> mPostData;
private Context mContext;
private Retrofit mOauthRetrofit;
private SharedPreferences mSharedPreferences;
private PaginationSynchronizer mPaginationSynchronizer;
private RequestManager glide;
private SubredditDao subredditDao;
@ -57,10 +59,11 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
private static final int VIEW_TYPE_LOADING = 1;
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, ArrayList<PostData> postData, PaginationSynchronizer paginationSynchronizer, boolean hasMultipleSubreddits) {
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, ArrayList<PostData> postData, PaginationSynchronizer paginationSynchronizer, boolean hasMultipleSubreddits) {
if(context != null) {
mContext = context;
mOauthRetrofit = oauthRetrofit;
mSharedPreferences = sharedPreferences;
mPostData = postData;
mPaginationSynchronizer = paginationSynchronizer;
this.hasMultipleSubreddits = hasMultipleSubreddits;
@ -91,17 +94,16 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
if(mPostData.get(holder.getAdapterPosition()) == null) {
Log.i("is null", Integer.toString(holder.getAdapterPosition()));
} else {
final int adapterPosition = holder.getAdapterPosition();
final String id = mPostData.get(adapterPosition).getFullName();
final String subredditName = mPostData.get(adapterPosition).getSubredditNamePrefixed();
final String postTime = mPostData.get(adapterPosition).getPostTime();
final String title = mPostData.get(adapterPosition).getTitle();
final String permalink = mPostData.get(adapterPosition).getPermalink();
int voteType = mPostData.get(adapterPosition).getVoteType();
int gilded = mPostData.get(adapterPosition).getGilded();
boolean nsfw = mPostData.get(adapterPosition).isNSFW();
final String id = mPostData.get(holder.getAdapterPosition()).getFullName();
final String subredditName = mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed();
final String postTime = mPostData.get(holder.getAdapterPosition()).getPostTime();
final String title = mPostData.get(holder.getAdapterPosition()).getTitle();
final String permalink = mPostData.get(holder.getAdapterPosition()).getPermalink();
int voteType = mPostData.get(holder.getAdapterPosition()).getVoteType();
int gilded = mPostData.get(holder.getAdapterPosition()).getGilded();
boolean nsfw = mPostData.get(holder.getAdapterPosition()).isNSFW();
if(mPostData.get(adapterPosition).getSubredditIconUrl() == null) {
if(mPostData.get(holder.getAdapterPosition()).getSubredditIconUrl() == null) {
new LoadSubredditIconAsyncTask(subredditDao, subredditName,
new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() {
@Override
@ -115,7 +117,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.into(((DataViewHolder) holder).subredditIconCircleImageView);
}
mPostData.get(adapterPosition).setSubredditIconUrl(iconImageUrl);
mPostData.get(holder.getAdapterPosition()).setSubredditIconUrl(iconImageUrl);
}
}
}).execute();
@ -132,7 +134,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
canStartActivity = false;
Intent intent = new Intent(mContext, ViewPostDetailActivity.class);
intent.putExtra(ViewPostDetailActivity.EXTRA_TITLE, title);
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPostData.get(adapterPosition));
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, mPostData.get(holder.getAdapterPosition()));
mContext.startActivity(intent);
}
}
@ -145,9 +147,9 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
mPostData.get(adapterPosition).getSubredditNamePrefixed().substring(2));
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
mPostData.get(adapterPosition).getSubredditNamePrefixed());
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
@ -163,9 +165,9 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
canStartActivity = false;
Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class);
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY,
mPostData.get(adapterPosition).getSubredditNamePrefixed().substring(2));
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed().substring(2));
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
mPostData.get(adapterPosition).getSubredditNamePrefixed());
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed());
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
mContext.startActivity(intent);
}
@ -256,10 +258,10 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(gifVideoUri);
intent.putExtra(ViewVideoActivity.TITLE_KEY, title);
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(adapterPosition).isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(adapterPosition).isDownloadableGifOrVideo());
if(mPostData.get(adapterPosition).isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(adapterPosition).getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(holder.getAdapterPosition()).isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo());
if(mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(holder.getAdapterPosition()).getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, id);
}
@ -277,10 +279,10 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
Intent intent = new Intent(mContext, ViewVideoActivity.class);
intent.setData(videoUri);
intent.putExtra(ViewVideoActivity.TITLE_KEY, title);
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(adapterPosition).isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(adapterPosition).isDownloadableGifOrVideo());
if(mPostData.get(adapterPosition).isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(adapterPosition).getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.IS_DASH_VIDEO_KEY, mPostData.get(holder.getAdapterPosition()).isDashVideo());
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo());
if(mPostData.get(holder.getAdapterPosition()).isDownloadableGifOrVideo()) {
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, mPostData.get(holder.getAdapterPosition()).getGifOrVideoDownloadUrl());
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
intent.putExtra(ViewVideoActivity.ID_KEY, id);
}
@ -319,12 +321,12 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
if (((DataViewHolder) holder).upvoteButton.getColorFilter() == null) {
((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
if(isDownvotedBefore) {
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() + 2));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 2));
} else {
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() + 1));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1));
}
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
mPostData.get(position).setVoteType(1);
@ -342,13 +344,13 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
((DataViewHolder) holder).downvoteButton.setColorFilter(downvoteButtonColorFilter);
}
}, id, RedditUtils.DIR_UPVOTE, holder.getAdapterPosition(), 1);
}, id, RedditUtils.DIR_UPVOTE, holder.getAdapterPosition());
} else {
//Upvoted before
((DataViewHolder) holder).upvoteButton.clearColorFilter();
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() - 1));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1));
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
mPostData.get(position).setVoteType(0);
@ -362,7 +364,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
((DataViewHolder) holder).upvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.colorPrimary), android.graphics.PorterDuff.Mode.SRC_IN);
mPostData.get(position).setScore(mPostData.get(position).getScore() + 1);
}
}, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition(), 1);
}, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition());
}
}
});
@ -377,12 +379,12 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
if (((DataViewHolder) holder).downvoteButton.getColorFilter() == null) {
((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
if (isUpvotedBefore) {
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() - 2));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 2));
} else {
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() - 1));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1));
}
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
mPostData.get(position).setVoteType(-1);
@ -400,13 +402,13 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
((DataViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter);
}
}, id, RedditUtils.DIR_DOWNVOTE, adapterPosition, 1);
}, id, RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition());
} else {
//Down voted before
((DataViewHolder) holder).downvoteButton.clearColorFilter();
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(adapterPosition).getScore() + 1));
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1));
VoteThing.voteThing(mContext, mOauthRetrofit, new VoteThing.VoteThingListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
@Override
public void onVoteThingSuccess(int position) {
mPostData.get(position).setVoteType(0);
@ -420,7 +422,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
mPostData.get(position).setScore(mPostData.get(position).getScore());
}
}, id, RedditUtils.DIR_UNVOTE, adapterPosition, 1);
}, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition());
}
}
});

View File

@ -27,7 +27,6 @@ class RedditUtils {
static final String SCOPE_KEY = "scope";
static final String SCOPE = "identity edit flair history modconfig modflair modlog modposts modwiki mysubreddits privatemessages read report save submit subscribe vote wikiedit wikiread";
static final String ACCESS_TOKEN_KEY = "access_token";
static final String EXPIRES_IN_KEY = "expires_in";
static final String AUTHORIZATION_KEY = "Authorization";
static final String AUTHORIZATION_BASE = "bearer ";

View File

@ -1,19 +1,17 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Calendar;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
@ -22,60 +20,35 @@ import retrofit2.converter.scalars.ScalarsConverterFactory;
*/
class RefreshAccessToken {
static String refreshAccessToken(/*Retrofit oauthRetrofit, */SharedPreferences sharedPreferences) {
String refreshToken = sharedPreferences.getString(SharedPreferencesUtils.REFRESH_TOKEN_KEY, "");
interface RefreshAccessTokenListener {
void onRefreshAccessTokenSuccess();
void onRefreshAccessTokenFail();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RedditUtils.API_BASE_URI)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
static void refreshAccessToken(final Context context, final RefreshAccessTokenListener refreshAccessTokenListener) {
if(context != null) {
String refreshToken = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.REFRESH_TOKEN_KEY, "");
RedditAPI api = retrofit.create(RedditAPI.class);
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RedditUtils.API_BASE_URI)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
Map<String, String> params = new HashMap<>();
params.put(RedditUtils.GRANT_TYPE_KEY, RedditUtils.GRANT_TYPE_REFRESH_TOKEN);
params.put(RedditUtils.REFRESH_TOKEN_KEY, refreshToken);
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> accessTokenCall = api.getAccessToken(RedditUtils.getHttpBasicAuthHeader(), params);
try {
Response response = accessTokenCall.execute();
JSONObject jsonObject = new JSONObject((String) response.body());
Map<String, String> params = new HashMap<>();
params.put(RedditUtils.GRANT_TYPE_KEY, RedditUtils.GRANT_TYPE_REFRESH_TOKEN);
params.put(RedditUtils.REFRESH_TOKEN_KEY, refreshToken);
String newAccessToken = jsonObject.getString(RedditUtils.ACCESS_TOKEN_KEY);
Call<String> accessTokenCall = api.getAccessToken(RedditUtils.getHttpBasicAuthHeader(), params);
accessTokenCall.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
try {
JSONObject jsonObject = new JSONObject(response.body());
String newAccessToken = jsonObject.getString(RedditUtils.ACCESS_TOKEN_KEY);
int expireIn = jsonObject.getInt(RedditUtils.EXPIRES_IN_KEY);
sharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, newAccessToken).apply();
long queryAccessTokenTime = Calendar.getInstance().getTimeInMillis();
SharedPreferences.Editor editor = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE).edit();
editor.putString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, newAccessToken);
editor.putInt(SharedPreferencesUtils.ACCESS_TOKEN_EXPIRE_INTERVAL_KEY, expireIn);
editor.putLong(SharedPreferencesUtils.QUERY_ACCESS_TOKEN_TIME_KEY, queryAccessTokenTime);
editor.apply();
Log.i("access token", newAccessToken);
refreshAccessTokenListener.onRefreshAccessTokenSuccess();
} catch (JSONException e) {
e.printStackTrace();
refreshAccessTokenListener.onRefreshAccessTokenFail();
Log.i("main activity", "Error parsing JSON object when getting the access token");
}
refreshAccessTokenListener.onRefreshAccessTokenSuccess();
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("call failed", t.getMessage());
refreshAccessTokenListener.onRefreshAccessTokenFail();
}
});
Log.i("access token", newAccessToken);
return newAccessToken;
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return "";
}
}

View File

@ -1,6 +1,7 @@
package ml.docilealligator.infinityforreddit;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@ -69,14 +70,15 @@ public class ViewPostDetailActivity extends AppCompatActivity {
private LoadSubredditIconAsyncTask mLoadSubredditIconAsyncTask;
@Inject
@Named("no_oauth")
@Inject @Named("no_oauth")
Retrofit mRetrofit;
@Inject
@Named("oauth")
@Inject @Named("oauth")
Retrofit mOauthRetrofit;
@Inject @Named("auth_info")
SharedPreferences mSharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -380,7 +382,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
scoreTextView.setText(Integer.toString(mPostData.getScore() + 1));
}
VoteThing.voteThing(ViewPostDetailActivity.this, mOauthRetrofit, new VoteThing.VoteThingWithoutPositionListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(1);
@ -398,13 +400,13 @@ public class ViewPostDetailActivity extends AppCompatActivity {
scoreTextView.setText(Integer.toString(mPostData.getScore()));
downvoteButton.setColorFilter(downVoteButtonColorFilter);
}
}, mPostData.getFullName(), RedditUtils.DIR_UPVOTE, 1);
}, mPostData.getFullName(), RedditUtils.DIR_UPVOTE);
} else {
//Upvoted before
upvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore() - 1));
VoteThing.voteThing(ViewPostDetailActivity.this, mOauthRetrofit, new VoteThing.VoteThingWithoutPositionListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(0);
@ -418,7 +420,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
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);
}, mPostData.getFullName(), RedditUtils.DIR_UNVOTE);
}
}
});
@ -440,7 +442,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
scoreTextView.setText(Integer.toString(mPostData.getScore() - 1));
}
VoteThing.voteThing(ViewPostDetailActivity.this, mOauthRetrofit, new VoteThing.VoteThingWithoutPositionListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(-1);
@ -458,13 +460,13 @@ public class ViewPostDetailActivity extends AppCompatActivity {
scoreTextView.setText(Integer.toString(mPostData.getScore()));
upvoteButton.setColorFilter(upvoteButtonColorFilter);
}
}, mPostData.getFullName(), RedditUtils.DIR_DOWNVOTE, 1);
}, mPostData.getFullName(), RedditUtils.DIR_DOWNVOTE);
} else {
//Down voted before
downvoteButton.clearColorFilter();
scoreTextView.setText(Integer.toString(mPostData.getScore() + 1));
VoteThing.voteThing(ViewPostDetailActivity.this, mOauthRetrofit, new VoteThing.VoteThingWithoutPositionListener() {
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingWithoutPositionListener() {
@Override
public void onVoteThingSuccess() {
mPostData.setVoteType(0);
@ -478,7 +480,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
scoreTextView.setText(Integer.toString(mPostData.getScore()));
mPostData.setScore(mPostData.getScore());
}
}, mPostData.getFullName(), RedditUtils.DIR_UNVOTE, 1);
}, mPostData.getFullName(), RedditUtils.DIR_UNVOTE);
}
}
});
@ -501,7 +503,7 @@ public class ViewPostDetailActivity extends AppCompatActivity {
if (commentData.size() > 0) {
CommentMultiLevelRecyclerViewAdapter adapter = new CommentMultiLevelRecyclerViewAdapter(
ViewPostDetailActivity.this, mRetrofit, mOauthRetrofit,
(ArrayList<CommentData>) commentData,
mSharedPreferences, (ArrayList<CommentData>) commentData,
mRecyclerView, mPostData.getSubredditNamePrefixed(),
mPostData.getId(), getResources().getConfiguration().locale);
mRecyclerView.removeItemClickListeners();

View File

@ -1,6 +1,6 @@
package ml.docilealligator.infinityforreddit;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
@ -27,19 +27,12 @@ class VoteThing {
void onVoteThingFail();
}
static void voteThing(final Context context, final Retrofit retrofit,
static void voteThing(final Retrofit retrofit, SharedPreferences authInfoSharedPreferences,
final VoteThingListener voteThingListener, final String fullName,
final String point, final int position, final int refreshTime) {
if(context != null) {
if(refreshTime < 0) {
voteThingListener.onVoteThingFail(position);
return;
}
final String point, final int position) {
RedditAPI api = retrofit.create(RedditAPI.class);
String accessToken = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
Map<String, String> params = new HashMap<>();
params.put(RedditUtils.DIR_KEY, point);
params.put(RedditUtils.ID_KEY, fullName);
@ -55,35 +48,17 @@ class VoteThing {
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("call failed", t.getMessage());
RefreshAccessToken.refreshAccessToken(context,
new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
voteThing(context, retrofit, voteThingListener, fullName, point, position, refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {
}
});
voteThingListener.onVoteThingFail(position);
}
});
}
}
static void voteThing(final Context context, final Retrofit retrofit,
static void voteThing(final Retrofit retrofit, SharedPreferences authInfoSharedPreferences,
final VoteThingWithoutPositionListener voteThingWithoutPositionListener,
final String fullName, final String point, final int refreshTime) {
if(context != null) {
if(refreshTime < 0) {
voteThingWithoutPositionListener.onVoteThingFail();
return;
}
final String fullName, final String point) {
RedditAPI api = retrofit.create(RedditAPI.class);
String accessToken = context.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
String accessToken = authInfoSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
Map<String, String> params = new HashMap<>();
params.put(RedditUtils.DIR_KEY, point);
params.put(RedditUtils.ID_KEY, fullName);
@ -99,18 +74,8 @@ class VoteThing {
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i("call failed", t.getMessage());
RefreshAccessToken.refreshAccessToken(context,
new RefreshAccessToken.RefreshAccessTokenListener() {
@Override
public void onRefreshAccessTokenSuccess() {
voteThing(context, retrofit, voteThingWithoutPositionListener, fullName, point, refreshTime - 1);
}
@Override
public void onRefreshAccessTokenFail() {}
});
voteThingWithoutPositionListener.onVoteThingFail();
}
});
}
}
}