mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2024-12-25 02:18:23 +01:00
Use Android Paging Library to load and display best posts. Loading best posts in a specific subreddit is broken. Fixed a bug which is PostViewModel's data becoming null after the app restart. Add notch support for Android Pie.
This commit is contained in:
parent
60b659e651
commit
45f67457fa
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -25,7 +25,7 @@
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -16,6 +16,10 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
@ -66,4 +70,5 @@ dependencies {
|
||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
||||
implementation 'com.github.santalu:aspect-ratio-imageview:1.0.6'
|
||||
implementation 'com.felipecsl:gifimageview:2.2.0'
|
||||
implementation "android.arch.paging:runtime:1.0.1"
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
class NetworkState {
|
||||
public enum Status{
|
||||
RUNNING,
|
||||
SUCCESS,
|
||||
FAILED
|
||||
}
|
||||
|
||||
|
||||
private final Status status;
|
||||
private final String msg;
|
||||
|
||||
static final NetworkState LOADED;
|
||||
static final NetworkState LOADING;
|
||||
|
||||
NetworkState(Status status, String msg) {
|
||||
this.status = status;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
static {
|
||||
LOADED=new NetworkState(Status.SUCCESS,"Success");
|
||||
LOADING=new NetworkState(Status.RUNNING,"Running");
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.arch.paging.PageKeyedDataSource;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
class PostDataSource extends PageKeyedDataSource<String, Post> {
|
||||
private Retrofit retrofit;
|
||||
private String accessToken;
|
||||
private Locale locale;
|
||||
private boolean isBestPost;
|
||||
|
||||
//private MutableLiveData networkState;
|
||||
private MutableLiveData initialLoading;
|
||||
|
||||
PostDataSource(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
|
||||
this.retrofit = retrofit;
|
||||
this.accessToken = accessToken;
|
||||
this.locale = locale;
|
||||
this.isBestPost = isBestPost;
|
||||
//networkState = new MutableLiveData();
|
||||
initialLoading = new MutableLiveData();
|
||||
|
||||
}
|
||||
|
||||
/*public MutableLiveData getNetworkState() {
|
||||
return networkState;
|
||||
}*/
|
||||
|
||||
public MutableLiveData getInitialLoading() {
|
||||
return initialLoading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, Post> callback) {
|
||||
initialLoading.postValue(NetworkState.LOADING);
|
||||
//networkState.postValue(NetworkState.LOADING);
|
||||
|
||||
RedditAPI api = retrofit.create(RedditAPI.class);
|
||||
|
||||
Call<String> bestPost = api.getBestPost(null, RedditUtils.getOAuthHeader(accessToken));
|
||||
bestPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if (response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), locale,
|
||||
new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
callback.onResult(newPosts, null, lastItem);
|
||||
initialLoading.postValue(NetworkState.LOADED);
|
||||
//networkState.postValue(NetworkState.LOADED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Log.i("Post fetch error", "Error parsing data");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.i("Post fetch error", response.message());
|
||||
initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
|
||||
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
String errorMessage = t == null ? "unknown error" : t.getMessage();
|
||||
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, Post> callback) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) {
|
||||
//networkState.postValue(NetworkState.LOADING);
|
||||
|
||||
RedditAPI api = retrofit.create(RedditAPI.class);
|
||||
Call<String> bestPost = api.getBestPost(params.key, RedditUtils.getOAuthHeader(accessToken));
|
||||
|
||||
bestPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if(response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
callback.onResult(newPosts, lastItem);
|
||||
//networkState.postValue(NetworkState.LOADED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Log.i("Best post", "Error parsing data");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.i("best post", response.message());
|
||||
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
String errorMessage = t == null ? "unknown error" : t.getMessage();
|
||||
//networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.arch.paging.DataSource;
|
||||
import android.arch.paging.PageKeyedDataSource;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
class PostDataSourceFactory extends DataSource.Factory {
|
||||
private Retrofit retrofit;
|
||||
private String accessToken;
|
||||
private Locale locale;
|
||||
private boolean isBestPost;
|
||||
|
||||
private MutableLiveData<PageKeyedDataSource<String, Post>> mutableLiveData;
|
||||
|
||||
PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
|
||||
this.retrofit = retrofit;
|
||||
this.accessToken = accessToken;
|
||||
this.locale = locale;
|
||||
this.isBestPost = isBestPost;
|
||||
mutableLiveData = new MutableLiveData<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSource create() {
|
||||
PostDataSource postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost);
|
||||
mutableLiveData.postValue(postDataSource);
|
||||
return postDataSource;
|
||||
}
|
||||
|
||||
public MutableLiveData<PageKeyedDataSource<String, Post>> getMutableLiveData() {
|
||||
return mutableLiveData;
|
||||
}
|
||||
}
|
@ -1,19 +1,15 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.Fragment;
|
||||
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;
|
||||
@ -21,15 +17,9 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
|
||||
@ -53,9 +43,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
|
||||
private LinearLayout mFetchPostErrorLinearLayout;
|
||||
private ImageView mFetchPostErrorImageView;
|
||||
|
||||
private String mLastItem;
|
||||
private PaginationSynchronizer mPaginationSynchronizer;
|
||||
|
||||
private boolean mIsBestPost;
|
||||
private String mSubredditName;
|
||||
|
||||
@ -76,14 +63,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(LAST_ITEM_STATE, mLastItem);
|
||||
outState.putBoolean(LOADING_STATE_STATE, mPaginationSynchronizer.isLoading());
|
||||
outState.putBoolean(LOAD_SUCCESS_STATE, mPaginationSynchronizer.isLoadingMorePostsSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@ -117,10 +96,11 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
|
||||
});*/
|
||||
|
||||
mIsBestPost = getArguments().getBoolean(IS_BEST_POST_KEY);
|
||||
|
||||
if(!mIsBestPost) {
|
||||
mSubredditName = getArguments().getString(SUBREDDIT_NAME_KEY);
|
||||
} else {
|
||||
mFetchPostErrorLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||
/*mFetchPostErrorLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(mIsBestPost) {
|
||||
@ -129,159 +109,35 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
|
||||
fetchPost();
|
||||
}
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
mPaginationSynchronizer = new PaginationSynchronizer();
|
||||
mPaginationSynchronizer.addLastItemSynchronizer(new LastItemSynchronizer() {
|
||||
@Override
|
||||
public void lastItemChanged(String lastItem) {
|
||||
mLastItem = lastItem;
|
||||
}
|
||||
});
|
||||
|
||||
mPostViewModel = ViewModelProviders.of(this).get(PostViewModel.class);
|
||||
mPostViewModel.getPosts().observe(this, new Observer<ArrayList<Post>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable ArrayList<Post> posts) {
|
||||
if(posts == null) {
|
||||
Log.i("datachange", Integer.toString(0));
|
||||
} else {
|
||||
Log.i("datachange", Integer.toString(posts.size()));
|
||||
mAdapter.changeDataSet(posts);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(mIsBestPost) {
|
||||
mAdapter = new PostRecyclerViewAdapter(getActivity(), mOauthRetrofit,
|
||||
mSharedPreferences, mPaginationSynchronizer, mIsBestPost);
|
||||
|
||||
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
|
||||
getActivity(), mOauthRetrofit, mPostViewModel, mLinearLayoutManager,
|
||||
mLastItem, mPaginationSynchronizer, mSubredditName, mIsBestPost,
|
||||
mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadingMorePostsSuccess(),
|
||||
getResources().getConfiguration().locale));
|
||||
mSharedPreferences, mIsBestPost);
|
||||
} else {
|
||||
mAdapter = new PostRecyclerViewAdapter(getActivity(), mRetrofit,
|
||||
mSharedPreferences, mPaginationSynchronizer, mIsBestPost);
|
||||
|
||||
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
|
||||
getActivity(), mRetrofit, mPostViewModel, mLinearLayoutManager,
|
||||
mLastItem, mPaginationSynchronizer, mSubredditName, mIsBestPost,
|
||||
mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadingMorePostsSuccess(),
|
||||
getResources().getConfiguration().locale));
|
||||
mSharedPreferences, mIsBestPost);
|
||||
}
|
||||
mPostRecyclerView.setAdapter(mAdapter);
|
||||
|
||||
if(savedInstanceState != null && savedInstanceState.containsKey(LAST_ITEM_STATE)) {
|
||||
mLastItem = savedInstanceState.getString(LAST_ITEM_STATE);
|
||||
String accessToken = getActivity().getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
|
||||
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
|
||||
|
||||
mPaginationSynchronizer.notifyLastItemChanged(mLastItem);
|
||||
mPaginationSynchronizer.setLoadSuccess(savedInstanceState.getBoolean(LOAD_SUCCESS_STATE));
|
||||
mPaginationSynchronizer.setLoadingState(savedInstanceState.getBoolean(LOADING_STATE_STATE));
|
||||
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
} else {
|
||||
if(mIsBestPost) {
|
||||
fetchBestPost();
|
||||
} else {
|
||||
fetchPost();
|
||||
}
|
||||
}
|
||||
PostViewModel.Factory factory = new PostViewModel.Factory(mOauthRetrofit, accessToken,
|
||||
getResources().getConfiguration().locale, mIsBestPost);
|
||||
mPostViewModel = ViewModelProviders.of(this, factory).get(PostViewModel.class);
|
||||
mPostViewModel.getPosts().observe(this, posts -> mAdapter.submitList(posts));
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private void fetchBestPost() {
|
||||
mFetchPostErrorLinearLayout.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
@Override
|
||||
public void refresh() {
|
||||
|
||||
RedditAPI api = mOauthRetrofit.create(RedditAPI.class);
|
||||
|
||||
String accessToken = getActivity().getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
|
||||
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
|
||||
Call<String> bestPost = api.getBestPost(mLastItem, RedditUtils.getOAuthHeader(accessToken));
|
||||
bestPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if(getActivity() != null) {
|
||||
if(response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), getResources().getConfiguration().locale,
|
||||
new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
if(isAdded() && getActivity() != null) {
|
||||
mLastItem = lastItem;
|
||||
mPaginationSynchronizer.notifyLastItemChanged(lastItem);
|
||||
mPostViewModel.setPosts(newPosts);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Log.i("Post fetch error", "Error parsing data");
|
||||
showErrorView();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.i("Post fetch error", response.message());
|
||||
showErrorView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
showErrorView();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchPost() {
|
||||
mFetchPostErrorLinearLayout.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
RedditAPI api = mRetrofit.create(RedditAPI.class);
|
||||
Call<String> getPost = api.getPost(mSubredditName, mLastItem);
|
||||
getPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if(getActivity() != null) {
|
||||
if(response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), getResources().getConfiguration().locale,
|
||||
new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
if(isAdded() && getActivity() != null) {
|
||||
mLastItem = lastItem;
|
||||
mPaginationSynchronizer.notifyLastItemChanged(lastItem);
|
||||
mPostViewModel.setPosts(newPosts);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Log.i("Post fetch error", "Error parsing data");
|
||||
showErrorView();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.i("Post fetch error", response.message());
|
||||
showErrorView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
showErrorView();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
private void showErrorView() {
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
if(mIsBestPost) {
|
||||
@ -303,32 +159,5 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
|
||||
});
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
mLastItem = null;
|
||||
mPostRecyclerView.clearOnScrollListeners();
|
||||
mPostRecyclerView.getRecycledViewPool().clear();
|
||||
|
||||
mPostViewModel.setPosts(null);
|
||||
|
||||
if(mIsBestPost) {
|
||||
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
|
||||
getActivity(), mOauthRetrofit, mPostViewModel, mLinearLayoutManager,
|
||||
mLastItem, mPaginationSynchronizer, mSubredditName, mIsBestPost,
|
||||
mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadingMorePostsSuccess(),
|
||||
getResources().getConfiguration().locale));
|
||||
|
||||
fetchBestPost();
|
||||
} else {
|
||||
mPostRecyclerView.addOnScrollListener(new PostPaginationScrollListener(
|
||||
getActivity(), mRetrofit, mPostViewModel, mLinearLayoutManager,
|
||||
mLastItem, mPaginationSynchronizer, mSubredditName, mIsBestPost,
|
||||
mPaginationSynchronizer.isLoading(), mPaginationSynchronizer.isLoadingMorePostsSuccess(),
|
||||
getResources().getConfiguration().locale));
|
||||
|
||||
fetchPost();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
/**
|
||||
* Created by alex on 3/12/18.
|
||||
*/
|
||||
|
||||
class PostPaginationScrollListener extends RecyclerView.OnScrollListener {
|
||||
private Context mContext;
|
||||
private Retrofit mRetrofit;
|
||||
private PostViewModel mPostViewModel;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
private PaginationSynchronizer mPaginationSynchronizer;
|
||||
|
||||
private String mSubredditName;
|
||||
private boolean isBestPost;
|
||||
private boolean isLoading;
|
||||
private boolean loadSuccess;
|
||||
private Locale locale;
|
||||
private String mLastItem;
|
||||
|
||||
PostPaginationScrollListener(Context context, Retrofit retrofit, PostViewModel postViewModel,
|
||||
LinearLayoutManager layoutManager, String lastItem,
|
||||
PaginationSynchronizer paginationSynchronizer, final String subredditName,
|
||||
final boolean isBestPost, boolean isLoading, boolean loadSuccess, Locale locale) {
|
||||
if(context != null) {
|
||||
mContext = context;
|
||||
mRetrofit = retrofit;
|
||||
mPostViewModel = postViewModel;
|
||||
mLayoutManager = layoutManager;
|
||||
mLastItem = lastItem;
|
||||
mPaginationSynchronizer = paginationSynchronizer;
|
||||
mSubredditName = subredditName;
|
||||
this.isBestPost = isBestPost;
|
||||
this.isLoading = isLoading;
|
||||
this.loadSuccess = loadSuccess;
|
||||
this.locale = locale;
|
||||
|
||||
PaginationRetryNotifier paginationRetryNotifier = new PaginationRetryNotifier() {
|
||||
@Override
|
||||
public void retry() {
|
||||
if (isBestPost) {
|
||||
fetchBestPost();
|
||||
} else {
|
||||
fetchPost(subredditName);
|
||||
}
|
||||
}
|
||||
};
|
||||
mPaginationSynchronizer.setPaginationRetryNotifier(paginationRetryNotifier);
|
||||
mPaginationSynchronizer.addLastItemSynchronizer(new LastItemSynchronizer() {
|
||||
@Override
|
||||
public void lastItemChanged(String lastItem) {
|
||||
mLastItem = lastItem;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
if(!isLoading && loadSuccess) {
|
||||
int visibleItemCount = mLayoutManager.getChildCount();
|
||||
int totalItemCount = mLayoutManager.getItemCount();
|
||||
int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
|
||||
|
||||
if((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) {
|
||||
if(isBestPost) {
|
||||
fetchBestPost();
|
||||
} else {
|
||||
fetchPost(mSubredditName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fetchBestPost() {
|
||||
isLoading = true;
|
||||
loadSuccess = false;
|
||||
mPaginationSynchronizer.setLoadingState(true);
|
||||
|
||||
RedditAPI api = mRetrofit.create(RedditAPI.class);
|
||||
|
||||
String accessToken = mContext.getSharedPreferences(SharedPreferencesUtils.AUTH_CODE_FILE_KEY, Context.MODE_PRIVATE)
|
||||
.getString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, "");
|
||||
Call<String> bestPost = api.getBestPost(mLastItem, RedditUtils.getOAuthHeader(accessToken));
|
||||
bestPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if(response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
if(mPostViewModel != null) {
|
||||
mPostViewModel.addPosts(newPosts);
|
||||
|
||||
mLastItem = lastItem;
|
||||
mPaginationSynchronizer.notifyLastItemChanged(lastItem);
|
||||
|
||||
isLoading = false;
|
||||
loadSuccess = true;
|
||||
mPaginationSynchronizer.setLoadingState(false);
|
||||
mPaginationSynchronizer.loadSuccess(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Toast.makeText(mContext, "Error parsing data", Toast.LENGTH_SHORT).show();
|
||||
Log.i("Best post", "Error parsing data");
|
||||
loadFailed();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show();
|
||||
Log.i("best post", response.message());
|
||||
loadFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
loadFailed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchPost(final String subredditName) {
|
||||
isLoading = true;
|
||||
loadSuccess = false;
|
||||
mPaginationSynchronizer.setLoadingState(true);
|
||||
|
||||
RedditAPI api = mRetrofit.create(RedditAPI.class);
|
||||
Call<String> getPost = api.getPost(subredditName, mLastItem);
|
||||
getPost.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(Call<String> call, retrofit2.Response<String> response) {
|
||||
if(response.isSuccessful()) {
|
||||
ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() {
|
||||
@Override
|
||||
public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) {
|
||||
if(mPostViewModel != null) {
|
||||
mPostViewModel.addPosts(newPosts);
|
||||
|
||||
mLastItem = lastItem;
|
||||
mPaginationSynchronizer.notifyLastItemChanged(lastItem);
|
||||
|
||||
isLoading = false;
|
||||
loadSuccess = true;
|
||||
mPaginationSynchronizer.setLoadingState(false);
|
||||
mPaginationSynchronizer.loadSuccess(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParsePostFail() {
|
||||
Toast.makeText(mContext, "Error parsing data", Toast.LENGTH_SHORT).show();
|
||||
Log.i("Best post", "Error parsing data");
|
||||
loadFailed();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show();
|
||||
Log.i("best post", response.message());
|
||||
loadFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
Toast.makeText(mContext, "Error getting best post", Toast.LENGTH_SHORT).show();
|
||||
loadFailed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadFailed() {
|
||||
isLoading = false;
|
||||
loadSuccess = false;
|
||||
mPaginationSynchronizer.setLoadingState(false);
|
||||
mPaginationSynchronizer.loadSuccess(false);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.arch.paging.PagedListAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -11,6 +12,7 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.customtabs.CustomTabsIntent;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.util.DiffUtil;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
@ -34,7 +36,7 @@ import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import CustomView.AspectRatioGifImageView;
|
||||
import butterknife.BindView;
|
||||
@ -47,12 +49,10 @@ import retrofit2.Retrofit;
|
||||
* Created by alex on 2/25/18.
|
||||
*/
|
||||
|
||||
class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private ArrayList<Post> mPostData;
|
||||
class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHolder> {
|
||||
private Context mContext;
|
||||
private Retrofit mOauthRetrofit;
|
||||
private SharedPreferences mSharedPreferences;
|
||||
private PaginationSynchronizer mPaginationSynchronizer;
|
||||
private RequestManager glide;
|
||||
private SubredditDao subredditDao;
|
||||
private boolean isLoadingMorePostSuccess = true;
|
||||
@ -62,21 +62,32 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
private static final int VIEW_TYPE_DATA = 0;
|
||||
private static final int VIEW_TYPE_LOADING = 1;
|
||||
|
||||
private int dataSize;
|
||||
private NetworkState networkState;
|
||||
|
||||
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, PaginationSynchronizer paginationSynchronizer, boolean hasMultipleSubreddits) {
|
||||
PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, boolean hasMultipleSubreddits) {
|
||||
super(DIFF_CALLBACK);
|
||||
if(context != null) {
|
||||
mContext = context;
|
||||
mOauthRetrofit = oauthRetrofit;
|
||||
mSharedPreferences = sharedPreferences;
|
||||
mPostData = new ArrayList<>();
|
||||
mPaginationSynchronizer = paginationSynchronizer;
|
||||
this.hasMultipleSubreddits = hasMultipleSubreddits;
|
||||
glide = Glide.with(mContext.getApplicationContext());
|
||||
subredditDao = SubredditRoomDatabase.getDatabase(mContext.getApplicationContext()).subredditDao();
|
||||
}
|
||||
}
|
||||
|
||||
static final DiffUtil.ItemCallback<Post> DIFF_CALLBACK = new DiffUtil.ItemCallback<Post>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull Post post, @NonNull Post t1) {
|
||||
return post.getId().equals(t1.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull Post post, @NonNull Post t1) {
|
||||
return post.getTitle().equals(t1.getTitle());
|
||||
}
|
||||
};
|
||||
|
||||
void setCanStartActivity(boolean canStartActivity) {
|
||||
this.canStartActivity = canStartActivity;
|
||||
}
|
||||
@ -93,27 +104,33 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
|
||||
onBindViewHolder(holder, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
||||
if(holder instanceof DataViewHolder) {
|
||||
if(mPostData.get(holder.getAdapterPosition()) == null) {
|
||||
Post post = getItem(position);
|
||||
if(post == null) {
|
||||
Log.i("is null", Integer.toString(holder.getAdapterPosition()));
|
||||
} else {
|
||||
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();
|
||||
final String id = post.getFullName();
|
||||
final String subredditName = post.getSubredditNamePrefixed();
|
||||
final String postTime = post.getPostTime();
|
||||
final String title = post.getTitle();
|
||||
final String permalink = post.getPermalink();
|
||||
int voteType = post.getVoteType();
|
||||
int gilded = post.getGilded();
|
||||
boolean nsfw = post.isNSFW();
|
||||
|
||||
if(mPostData.get(holder.getAdapterPosition()).getSubredditIconUrl() == null) {
|
||||
if(post.getSubredditIconUrl() == null) {
|
||||
new LoadSubredditIconAsyncTask(subredditDao, subredditName,
|
||||
new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() {
|
||||
@Override
|
||||
public void loadIconSuccess(String iconImageUrl) {
|
||||
if(mContext != null && !mPostData.isEmpty()) {
|
||||
if(mContext != null && getItemCount() > 0) {
|
||||
if(!iconImageUrl.equals("")) {
|
||||
glide.load(iconImageUrl)
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
|
||||
@ -142,13 +159,13 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
}
|
||||
|
||||
if(holder.getAdapterPosition() >= 0) {
|
||||
mPostData.get(holder.getAdapterPosition()).setSubredditIconUrl(iconImageUrl);
|
||||
post.setSubredditIconUrl(iconImageUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).execute();
|
||||
} else if(!mPostData.get(position).getSubredditIconUrl().equals("")) {
|
||||
glide.load(mPostData.get(position).getSubredditIconUrl())
|
||||
} else if(!post.getSubredditIconUrl().equals("")) {
|
||||
glide.load(post.getSubredditIconUrl())
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
|
||||
.error(glide.load(R.drawable.subreddit_default_icon))
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@ -181,7 +198,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(holder.getAdapterPosition()));
|
||||
intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post);
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
}
|
||||
@ -194,9 +211,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(holder.getAdapterPosition()).getSubredditNamePrefixed().substring(2));
|
||||
post.getSubredditNamePrefixed().substring(2));
|
||||
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
|
||||
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed());
|
||||
post.getSubredditNamePrefixed());
|
||||
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
@ -212,9 +229,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(holder.getAdapterPosition()).getSubredditNamePrefixed().substring(2));
|
||||
post.getSubredditNamePrefixed().substring(2));
|
||||
intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_VALUE_KEY,
|
||||
mPostData.get(holder.getAdapterPosition()).getSubredditNamePrefixed());
|
||||
post.getSubredditNamePrefixed());
|
||||
intent.putExtra(ViewSubredditDetailActivity.EXTRA_QUERY_BY_ID_KEY, false);
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
@ -222,7 +239,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
});
|
||||
((DataViewHolder) holder).postTimeTextView.setText(postTime);
|
||||
((DataViewHolder) holder).titleTextView.setText(title);
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore()));
|
||||
|
||||
if(gilded > 0) {
|
||||
((DataViewHolder) holder).gildedImageView.setVisibility(View.VISIBLE);
|
||||
@ -247,29 +264,29 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
break;
|
||||
}
|
||||
|
||||
if(mPostData.get(position).getPostType() != Post.TEXT_TYPE && mPostData.get(position).getPostType() != Post.NO_PREVIEW_LINK_TYPE) {
|
||||
if(post.getPostType() != Post.TEXT_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) {
|
||||
((DataViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
|
||||
((DataViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
|
||||
((DataViewHolder) holder).imageView.setVisibility(View.VISIBLE);
|
||||
((DataViewHolder) holder).imageView
|
||||
.setRatio((float) mPostData.get(position).getPreviewHeight() / mPostData.get(position).getPreviewWidth());
|
||||
loadImage(holder, mPostData.get(holder.getAdapterPosition()));
|
||||
.setRatio((float) post.getPreviewHeight() / post.getPreviewWidth());
|
||||
loadImage(holder, post);
|
||||
}
|
||||
|
||||
if(!hasMultipleSubreddits && mPostData.get(position).isStickied()) {
|
||||
if(!hasMultipleSubreddits && post.isStickied()) {
|
||||
((DataViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE);
|
||||
glide.load(R.drawable.thumbtack).into(((DataViewHolder) holder).stickiedPostImageView);
|
||||
}
|
||||
|
||||
if(mPostData.get(holder.getAdapterPosition()).isCrosspost()) {
|
||||
if(post.isCrosspost()) {
|
||||
((DataViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
switch (mPostData.get(position).getPostType()) {
|
||||
switch (post.getPostType()) {
|
||||
case Post.IMAGE_TYPE:
|
||||
((DataViewHolder) holder).typeTextView.setText("IMAGE");
|
||||
|
||||
final String imageUrl = mPostData.get(position).getUrl();
|
||||
final String imageUrl = post.getUrl();
|
||||
((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
@ -293,24 +310,24 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
builder.addDefaultShareMenuItem();
|
||||
builder.setToolbarColor(mContext.getResources().getColor(R.color.colorPrimary));
|
||||
CustomTabsIntent customTabsIntent = builder.build();
|
||||
customTabsIntent.launchUrl(mContext, Uri.parse(mPostData.get(holder.getAdapterPosition()).getUrl()));
|
||||
customTabsIntent.launchUrl(mContext, Uri.parse(post.getUrl()));
|
||||
}
|
||||
});
|
||||
break;
|
||||
case Post.GIF_VIDEO_TYPE:
|
||||
((DataViewHolder) holder).typeTextView.setText("GIF");
|
||||
|
||||
final Uri gifVideoUri = Uri.parse(mPostData.get(position).getVideoUrl());
|
||||
final Uri gifVideoUri = Uri.parse(post.getVideoUrl());
|
||||
((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
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(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.IS_DASH_VIDEO_KEY, post.isDashVideo());
|
||||
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, post.isDownloadableGifOrVideo());
|
||||
if(post.isDownloadableGifOrVideo()) {
|
||||
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, post.getGifOrVideoDownloadUrl());
|
||||
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
|
||||
intent.putExtra(ViewVideoActivity.ID_KEY, id);
|
||||
}
|
||||
@ -321,17 +338,17 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
case Post.VIDEO_TYPE:
|
||||
((DataViewHolder) holder).typeTextView.setText("VIDEO");
|
||||
|
||||
final Uri videoUri = Uri.parse(mPostData.get(position).getVideoUrl());
|
||||
final Uri videoUri = Uri.parse(post.getVideoUrl());
|
||||
((DataViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
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(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.IS_DASH_VIDEO_KEY, post.isDashVideo());
|
||||
intent.putExtra(ViewVideoActivity.IS_DOWNLOADABLE_KEY, post.isDownloadableGifOrVideo());
|
||||
if(post.isDownloadableGifOrVideo()) {
|
||||
intent.putExtra(ViewVideoActivity.DOWNLOAD_URL_KEY, post.getGifOrVideoDownloadUrl());
|
||||
intent.putExtra(ViewVideoActivity.SUBREDDIT_KEY, subredditName);
|
||||
intent.putExtra(ViewVideoActivity.ID_KEY, id);
|
||||
}
|
||||
@ -341,7 +358,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
break;
|
||||
case Post.NO_PREVIEW_LINK_TYPE:
|
||||
((DataViewHolder) holder).typeTextView.setText("LINK");
|
||||
final String noPreviewLinkUrl = mPostData.get(position).getUrl();
|
||||
final String noPreviewLinkUrl = post.getUrl();
|
||||
((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE);
|
||||
((DataViewHolder) holder).noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -371,19 +388,19 @@ 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(holder.getAdapterPosition()).getScore() + 2));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + 2));
|
||||
} else {
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + 1));
|
||||
}
|
||||
|
||||
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
|
||||
@Override
|
||||
public void onVoteThingSuccess(int position) {
|
||||
mPostData.get(position).setVoteType(1);
|
||||
post.setVoteType(1);
|
||||
if(isDownvotedBefore) {
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore() + 2);
|
||||
post.setScore(post.getScore() + 2);
|
||||
} else {
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore() + 1);
|
||||
post.setScore(post.getScore() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,28 +408,28 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
public void onVoteThingFail(int position) {
|
||||
Toast.makeText(mContext, "Cannot upvote this post", Toast.LENGTH_SHORT).show();
|
||||
((DataViewHolder) holder).upvoteButton.clearColorFilter();
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore()));
|
||||
((DataViewHolder) holder).downvoteButton.setColorFilter(downvoteButtonColorFilter);
|
||||
}
|
||||
}, id, RedditUtils.DIR_UPVOTE, holder.getAdapterPosition());
|
||||
} else {
|
||||
//Upvoted before
|
||||
((DataViewHolder) holder).upvoteButton.clearColorFilter();
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() - 1));
|
||||
|
||||
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
|
||||
@Override
|
||||
public void onVoteThingSuccess(int position) {
|
||||
mPostData.get(position).setVoteType(0);
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore() - 1);
|
||||
post.setVoteType(0);
|
||||
post.setScore(post.getScore() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteThingFail(int position) {
|
||||
Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show();
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore() + 1));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + 1));
|
||||
((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);
|
||||
post.setScore(post.getScore() + 1);
|
||||
}
|
||||
}, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition());
|
||||
}
|
||||
@ -429,19 +446,19 @@ 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(holder.getAdapterPosition()).getScore() - 2));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() - 2));
|
||||
} else {
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() - 1));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() - 1));
|
||||
}
|
||||
|
||||
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
|
||||
@Override
|
||||
public void onVoteThingSuccess(int position) {
|
||||
mPostData.get(position).setVoteType(-1);
|
||||
post.setVoteType(-1);
|
||||
if(isUpvotedBefore) {
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore() - 2);
|
||||
post.setScore(post.getScore() - 2);
|
||||
} else {
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore() - 1);
|
||||
post.setScore(post.getScore() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,28 +466,28 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
public void onVoteThingFail(int position) {
|
||||
Toast.makeText(mContext, "Cannot downvote this post", Toast.LENGTH_SHORT).show();
|
||||
((DataViewHolder) holder).downvoteButton.clearColorFilter();
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore()));
|
||||
((DataViewHolder) holder).upvoteButton.setColorFilter(upvoteButtonColorFilter);
|
||||
}
|
||||
}, id, RedditUtils.DIR_DOWNVOTE, holder.getAdapterPosition());
|
||||
} else {
|
||||
//Down voted before
|
||||
((DataViewHolder) holder).downvoteButton.clearColorFilter();
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(holder.getAdapterPosition()).getScore() + 1));
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore() + 1));
|
||||
|
||||
VoteThing.voteThing(mOauthRetrofit, mSharedPreferences, new VoteThing.VoteThingListener() {
|
||||
@Override
|
||||
public void onVoteThingSuccess(int position) {
|
||||
mPostData.get(position).setVoteType(0);
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore());
|
||||
post.setVoteType(0);
|
||||
post.setScore(post.getScore());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteThingFail(int position) {
|
||||
Toast.makeText(mContext, "Cannot unvote this post", Toast.LENGTH_SHORT).show();
|
||||
((DataViewHolder) holder).downvoteButton.setColorFilter(ContextCompat.getColor(mContext, R.color.minusButtonColor), android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(mPostData.get(position).getScore()));
|
||||
mPostData.get(position).setScore(mPostData.get(position).getScore());
|
||||
((DataViewHolder) holder).scoreTextView.setText(Integer.toString(post.getScore()));
|
||||
post.setScore(post.getScore());
|
||||
}
|
||||
}, id, RedditUtils.DIR_UNVOTE, holder.getAdapterPosition());
|
||||
}
|
||||
@ -492,7 +509,7 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
((LoadingViewHolder) holder).retryButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mPaginationSynchronizer.getPaginationRetryNotifier().retry();
|
||||
//mPaginationSynchronizer.getPaginationRetryNotifier().retry();
|
||||
((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
|
||||
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE);
|
||||
}
|
||||
@ -512,12 +529,12 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
}
|
||||
};
|
||||
|
||||
mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier);
|
||||
/*mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier);
|
||||
|
||||
if(!mPaginationSynchronizer.isLoadingMorePostsSuccess()) {
|
||||
((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE);
|
||||
((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -553,27 +570,30 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
imageRequestBuilder.into(((DataViewHolder) holder).imageView);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if(mPostData == null || mPostData.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return mPostData.size() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (position >= mPostData.size() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA);
|
||||
return (position >= getItemCount() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA);
|
||||
}
|
||||
|
||||
void changeDataSet(ArrayList<Post> posts) {
|
||||
mPostData = posts;
|
||||
if(dataSize == 0 || posts.size() <= dataSize) {
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
notifyItemRangeInserted(dataSize, posts.size() - dataSize);
|
||||
private boolean hasExtraRow() {
|
||||
return networkState != null && networkState != NetworkState.LOADED;
|
||||
}
|
||||
|
||||
public void setNetworkState(NetworkState newNetworkState) {
|
||||
NetworkState previousState = this.networkState;
|
||||
boolean previousExtraRow = hasExtraRow();
|
||||
this.networkState = newNetworkState;
|
||||
boolean newExtraRow = hasExtraRow();
|
||||
if (previousExtraRow != newExtraRow) {
|
||||
if (previousExtraRow) {
|
||||
notifyItemRemoved(getItemCount());
|
||||
} else {
|
||||
notifyItemInserted(getItemCount());
|
||||
}
|
||||
} else if (newExtraRow && previousState != newNetworkState) {
|
||||
notifyItemChanged(getItemCount() - 1);
|
||||
}
|
||||
dataSize = posts.size();
|
||||
}
|
||||
|
||||
class DataViewHolder extends RecyclerView.ViewHolder {
|
||||
|
@ -1,30 +1,66 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.arch.lifecycle.ViewModel;
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
import android.arch.paging.LivePagedListBuilder;
|
||||
import android.arch.paging.PageKeyedDataSource;
|
||||
import android.arch.paging.PagedList;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class PostViewModel extends ViewModel {
|
||||
private MutableLiveData<ArrayList<Post>> posts = new MutableLiveData<>();
|
||||
private Executor executor;
|
||||
LiveData<NetworkState> networkState;
|
||||
LiveData<PagedList<Post>> posts;
|
||||
LiveData<PageKeyedDataSource<String, Post>> liveDataSource;
|
||||
|
||||
LiveData<ArrayList<Post>> getPosts() {
|
||||
if(posts == null) {
|
||||
setPosts(new ArrayList<Post>());
|
||||
}
|
||||
public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
|
||||
//executor = Executors.newFixedThreadPool(5);
|
||||
|
||||
PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, isBestPost);
|
||||
/*networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(),
|
||||
(Function<PostDataSource, LiveData<NetworkState>>) PostDataSource::getNetworkState);*/
|
||||
liveDataSource = postDataSourceFactory.getMutableLiveData();
|
||||
|
||||
PagedList.Config pagedListConfig =
|
||||
(new PagedList.Config.Builder())
|
||||
.setEnablePlaceholders(false)
|
||||
.setPageSize(25)
|
||||
.build();
|
||||
|
||||
posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build();
|
||||
}
|
||||
|
||||
LiveData<PagedList<Post>> getPosts() {
|
||||
return posts;
|
||||
}
|
||||
|
||||
void setPosts(ArrayList<Post> posts) {
|
||||
this.posts.postValue(posts);
|
||||
}
|
||||
/*public LiveData<NetworkState> getNetworkState() {
|
||||
return networkState;
|
||||
}*/
|
||||
|
||||
void addPosts(ArrayList<Post> newPosts) {
|
||||
ArrayList<Post> posts = this.posts.getValue();
|
||||
if(posts != null) {
|
||||
posts.addAll(newPosts);
|
||||
this.posts.postValue(posts);
|
||||
public static class Factory extends ViewModelProvider.NewInstanceFactory {
|
||||
private Retrofit retrofit;
|
||||
private String accessToken;
|
||||
private Locale locale;
|
||||
private boolean isBestPost;
|
||||
|
||||
public Factory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) {
|
||||
this.retrofit = retrofit;
|
||||
this.accessToken = accessToken;
|
||||
this.locale = locale;
|
||||
this.isBestPost = isBestPost;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
return (T) new PostViewModel(retrofit, accessToken, locale, isBestPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,40 +321,6 @@ 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(mPost.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();
|
||||
}
|
||||
};*/
|
||||
|
||||
mUpvoteButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
12
app/src/main/res/values-v28/styles.xml
Normal file
12
app/src/main/res/values-v28/styles.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -20,6 +20,9 @@ allprojects {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url 'https://dl.bintray.com/sysdata/maven' }
|
||||
maven { url 'http://repo.pageturner-reader.org' }
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user