aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Ning <chineseperson5@gmail.com>2018-12-27 03:29:02 +0000
committerAlex Ning <chineseperson5@gmail.com>2018-12-27 03:29:02 +0000
commit45f67457fa6bf49fdf2648e1dc3a3802beac41b4 (patch)
tree30ecbc7539372376cdc73ccdea44ad214f7ef17b
parent60b659e651b4d8e7d9ca26b17ba8990497022ed1 (diff)
downloadinfinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar.gz
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar.bz2
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar.lz
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar.xz
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.tar.zst
infinity-for-reddit-45f67457fa6bf49fdf2648e1dc3a3802beac41b4.zip
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.
-rw-r--r--.idea/caches/build_file_checksums.serbin533 -> 533 bytes
-rw-r--r--.idea/misc.xml2
-rw-r--r--app/build.gradle5
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java34
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java124
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java37
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java199
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java197
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java196
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java66
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java34
-rw-r--r--app/src/main/res/values-v28/styles.xml12
-rw-r--r--build.gradle3
13 files changed, 389 insertions, 520 deletions
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index a7bbc0e3..dd278ac4 100644
--- a/.idea/caches/build_file_checksums.ser
+++ b/.idea/caches/build_file_checksums.ser
Binary files differ
diff --git a/.idea/misc.xml b/.idea/misc.xml
index dc345694..cc51e58e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -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">
diff --git a/app/build.gradle b/app/build.gradle
index 317de2a4..c9d61af9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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"
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java
new file mode 100644
index 00000000..495f54c2
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java
@@ -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;
+ }
+}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java
new file mode 100644
index 00000000..41ba65d1
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java
@@ -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));
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java
new file mode 100644
index 00000000..20cda5ca
--- /dev/null
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java
@@ -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;
+ }
+}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java
index e3a2ba5a..52c92813 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java
@@ -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;
@@ -77,14 +64,6 @@ public class PostFragment extends Fragment implements FragmentCommunicator {
}
@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();
if(mPostRecyclerView.getAdapter() != null) {
@@ -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);
-
- 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();
- }
- }
-
- return rootView;
- }
-
- private void fetchBestPost() {
- mFetchPostErrorLinearLayout.setVisibility(View.GONE);
- mProgressBar.setVisibility(View.VISIBLE);
-
- 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();
- }
- }
- }
+ 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));
- @Override
- public void onFailure(Call<String> call, Throwable t) {
- showErrorView();
- }
- });
+ return rootView;
}
- 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 refresh() {
- @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();
- }
- }
+ }*/
} \ No newline at end of file
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java
deleted file mode 100644
index 0c11e305..00000000
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostPaginationScrollListener.java
+++ /dev/null
@@ -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);
- }
-} \ No newline at end of file
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java
index 66c29d65..2d6f54aa 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java
@@ -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;
}
@@ -94,26 +105,32 @@ 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();
-
- if(mPostData.get(holder.getAdapterPosition()).getSubredditIconUrl() == null) {
+ 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(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 {
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java
index af6c1f31..0be971eb 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java
@@ -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>());
- }
- return posts;
+ 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();
}
- void setPosts(ArrayList<Post> posts) {
- this.posts.postValue(posts);
+ LiveData<PagedList<Post>> getPosts() {
+ return posts;
}
- void addPosts(ArrayList<Post> newPosts) {
- ArrayList<Post> posts = this.posts.getValue();
- if(posts != null) {
- posts.addAll(newPosts);
- this.posts.postValue(posts);
+ /*public LiveData<NetworkState> getNetworkState() {
+ return networkState;
+ }*/
+
+ 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);
}
}
}
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
index 27d152d1..6c8f209e 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java
@@ -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) {
diff --git a/app/src/main/res/values-v28/styles.xml b/app/src/main/res/values-v28/styles.xml
new file mode 100644
index 00000000..7b88cdf3
--- /dev/null
+++ b/app/src/main/res/values-v28/styles.xml
@@ -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>
diff --git a/build.gradle b/build.gradle
index 35d0051f..8a7b6fa0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -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()
}
}