diff options
Diffstat (limited to 'app')
10 files changed, 239 insertions, 238 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java index 495f54c2..4e741025 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/NetworkState.java @@ -2,7 +2,7 @@ package ml.docilealligator.infinityforreddit; class NetworkState { public enum Status{ - RUNNING, + LOADING, SUCCESS, FAILED } @@ -21,7 +21,7 @@ class NetworkState { static { LOADED=new NetworkState(Status.SUCCESS,"Success"); - LOADING=new NetworkState(Status.RUNNING,"Running"); + LOADING=new NetworkState(Status.LOADING,"Loading"); } public Status getStatus() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java index 9409de52..87c65fad 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSource.java @@ -19,16 +19,21 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { private boolean isBestPost; private String subredditName; - private MutableLiveData networkState; - private MutableLiveData initialLoading; + private MutableLiveData<NetworkState> paginationNetworkStateLiveData; + private MutableLiveData<NetworkState> initialLoadStateLiveData; + + private LoadInitialParams<String> initialParams; + private LoadInitialCallback<String, Post> initialCallback; + private LoadParams<String> params; + private LoadCallback<String, Post> callback; 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(); + paginationNetworkStateLiveData = new MutableLiveData(); + initialLoadStateLiveData = new MutableLiveData(); } @@ -37,22 +42,24 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { this.locale = locale; this.isBestPost = isBestPost; this.subredditName = subredditName; - networkState = new MutableLiveData(); - initialLoading = new MutableLiveData(); + paginationNetworkStateLiveData = new MutableLiveData(); + initialLoadStateLiveData = new MutableLiveData(); } - MutableLiveData getNetworkState() { - return networkState; + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; } - MutableLiveData getInitialLoading() { - return initialLoading; + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; } @Override public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, Post> callback) { - initialLoading.postValue(NetworkState.LOADING); - networkState.postValue(NetworkState.LOADING); + initialParams = params; + initialCallback = callback; + + initialLoadStateLiveData.postValue(NetworkState.LOADING); if(isBestPost) { RedditAPI api = retrofit.create(RedditAPI.class); @@ -67,26 +74,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, null, lastItem); - initialLoading.postValue(NetworkState.LOADED); - networkState.postValue(NetworkState.LOADED); + initialLoadStateLiveData.postValue(NetworkState.LOADED); } @Override public void onParsePostFail() { Log.i("Post fetch error", "Error parsing data"); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "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())); + initialLoadStateLiveData.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)); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); } else { @@ -101,26 +107,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, null, lastItem); - initialLoading.postValue(NetworkState.LOADED); - networkState.postValue(NetworkState.LOADED); + initialLoadStateLiveData.postValue(NetworkState.LOADED); } @Override public void onParsePostFail() { Log.i("Post fetch error", "Error parsing data"); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "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())); + initialLoadStateLiveData.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)); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); } @@ -133,7 +138,10 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void loadAfter(@NonNull LoadParams<String> params, @NonNull final LoadCallback<String, Post> callback) { - networkState.postValue(NetworkState.LOADING); + this.params = params; + this.callback = callback; + + paginationNetworkStateLiveData.postValue(NetworkState.LOADING); if(isBestPost) { RedditAPI api = retrofit.create(RedditAPI.class); @@ -147,24 +155,25 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); - networkState.postValue(NetworkState.LOADED); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override public void onParsePostFail() { Log.i("Best post", "Error parsing data"); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } }); } else { Log.i("best post", response.message()); - networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + paginationNetworkStateLiveData.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)); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); } else { @@ -178,26 +187,35 @@ class PostDataSource extends PageKeyedDataSource<String, Post> { @Override public void onParsePostSuccess(ArrayList<Post> newPosts, String lastItem) { callback.onResult(newPosts, lastItem); - networkState.postValue(NetworkState.LOADED); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } @Override public void onParsePostFail() { Log.i("Best post", "Error parsing data"); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); } }); } else { - Log.i("best post", response.message()); - networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + Log.i("Best post", response.message()); + paginationNetworkStateLiveData.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)); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); } }); } } + + void retry() { + loadInitial(initialParams, initialCallback); + } + + void retryLoadingMore() { + loadAfter(params, callback); + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java index db05e0e0..27c01fff 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostDataSourceFactory.java @@ -11,40 +11,48 @@ class PostDataSourceFactory extends DataSource.Factory { private Retrofit retrofit; private String accessToken; private Locale locale; - private boolean isBestPost; private String subredditName; - private MutableLiveData<PostDataSource> mutableLiveData; + private PostDataSource postDataSource; + private MutableLiveData<PostDataSource> postDataSourceLiveData; PostDataSourceFactory(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) { this.retrofit = retrofit; this.accessToken = accessToken; this.locale = locale; - this.isBestPost = isBestPost; - mutableLiveData = new MutableLiveData<>(); + postDataSourceLiveData = new MutableLiveData<>(); + + if(isBestPost) { + postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost); + } else { + postDataSource = new PostDataSource(retrofit, locale, isBestPost, subredditName); + } } PostDataSourceFactory(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) { this.retrofit = retrofit; this.locale = locale; - this.isBestPost = isBestPost; - mutableLiveData = new MutableLiveData<>(); this.subredditName = subredditName; - } + postDataSourceLiveData = new MutableLiveData<>(); - @Override - public DataSource create() { - PostDataSource postDataSource; if(isBestPost) { postDataSource = new PostDataSource(retrofit, accessToken, locale, isBestPost); } else { postDataSource = new PostDataSource(retrofit, locale, isBestPost, subredditName); } - mutableLiveData.postValue(postDataSource); + } + + @Override + public DataSource create() { + postDataSourceLiveData.postValue(postDataSource); return postDataSource; } - public MutableLiveData<PostDataSource> getMutableLiveData() { - return mutableLiveData; + public MutableLiveData<PostDataSource> getPostDataSourceLiveData() { + return postDataSourceLiveData; + } + + PostDataSource getPostDataSource() { + return postDataSource; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index f7dd68ef..c4e10e45 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -11,6 +11,7 @@ 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; @@ -98,24 +99,15 @@ public class PostFragment extends Fragment implements FragmentCommunicator { if(!mIsBestPost) { mSubredditName = getArguments().getString(SUBREDDIT_NAME_KEY); } else { - /*mFetchPostErrorLinearLayout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if(mIsBestPost) { - fetchBestPost(); - } else { - fetchPost(); - } - } - });*/ + mFetchPostErrorLinearLayout.setOnClickListener(view -> mPostViewModel.retry()); } if(mIsBestPost) { mAdapter = new PostRecyclerViewAdapter(getActivity(), mOauthRetrofit, - mSharedPreferences, mIsBestPost); + mSharedPreferences, mIsBestPost, () -> mPostViewModel.retryLoadingMore()); } else { mAdapter = new PostRecyclerViewAdapter(getActivity(), mRetrofit, - mSharedPreferences, mIsBestPost); + mSharedPreferences, mIsBestPost, () -> mPostViewModel.retryLoadingMore()); } mPostRecyclerView.setAdapter(mAdapter); @@ -132,16 +124,23 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } mPostViewModel = ViewModelProviders.of(this, factory).get(PostViewModel.class); mPostViewModel.getPosts().observe(this, posts -> mAdapter.submitList(posts)); + mPostViewModel.getInitialLoadingState().observe(this, networkState -> { if(networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { mProgressBar.setVisibility(View.GONE); } else if(networkState.getStatus().equals(NetworkState.Status.FAILED)) { showErrorView(); } else { + mFetchPostErrorLinearLayout.setVisibility(View.GONE); mProgressBar.setVisibility(View.VISIBLE); } }); + mPostViewModel.getPaginationNetworkState().observe(this, networkState -> { + Log.i("networkstate", networkState.getStatus().toString()); + mAdapter.setNetworkState(networkState); + }); + return rootView; } @@ -159,16 +158,7 @@ public class PostFragment extends Fragment implements FragmentCommunicator { } } else { Snackbar snackbar = Snackbar.make(mCoordinatorLayout, "Error getting post", Snackbar.LENGTH_INDEFINITE); - snackbar.setAction(R.string.retry, new View.OnClickListener() { - @Override - public void onClick(View view) { - /*if (mIsBestPost) { - fetchBestPost(); - } else { - fetchPost(); - }*/ - } - }); + snackbar.setAction(R.string.retry, view -> mPostViewModel.retry()); snackbar.show(); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index 9ec8b83b..f9c3332c 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -21,7 +21,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; @@ -36,8 +35,6 @@ import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; -import java.util.List; - import CustomView.AspectRatioGifImageView; import SubredditDatabase.SubredditDao; import SubredditDatabase.SubredditRoomDatabase; @@ -57,16 +54,22 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo private SharedPreferences mSharedPreferences; private RequestManager glide; private SubredditDao subredditDao; - private boolean isLoadingMorePostSuccess = true; private boolean canStartActivity = true; private boolean hasMultipleSubreddits; private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_LOADING = 1; + private static final int VIEW_TYPE_ERROR = 1; + private static final int VIEW_TYPE_LOADING = 2; private NetworkState networkState; + private RetryLoadingMoreCallback retryLoadingMoreCallback; + + interface RetryLoadingMoreCallback { + void retryLoadingMore(); + } - PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, boolean hasMultipleSubreddits) { + PostRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, SharedPreferences sharedPreferences, boolean hasMultipleSubreddits, + RetryLoadingMoreCallback retryLoadingMoreCallback) { super(DIFF_CALLBACK); if(context != null) { mContext = context; @@ -75,6 +78,7 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo this.hasMultipleSubreddits = hasMultipleSubreddits; glide = Glide.with(mContext.getApplicationContext()); subredditDao = SubredditRoomDatabase.getDatabase(mContext.getApplicationContext()).subredditDao(); + this.retryLoadingMoreCallback = retryLoadingMoreCallback; } } @@ -100,18 +104,16 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo if(viewType == VIEW_TYPE_DATA) { CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post, parent, false); return new DataViewHolder(cardView); + } else if(viewType == VIEW_TYPE_ERROR) { + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false); + return new ErrorViewHolder(relativeLayout); } else { - LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_progress_bar, parent, false); - return new LoadingViewHolder(linearLayout); + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false); + return new LoadingViewHolder(relativeLayout); } } @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) { Post post = getItem(position); @@ -129,40 +131,37 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo if(post.getSubredditIconUrl() == null) { new LoadSubredditIconAsyncTask(subredditDao, subredditName, - new LoadSubredditIconAsyncTask.LoadSubredditIconAsyncTaskListener() { - @Override - public void loadIconSuccess(String iconImageUrl) { - if(mContext != null && getItemCount() > 0) { - if(!iconImageUrl.equals("")) { - glide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon)) - .listener(new RequestListener<Drawable>() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { - return false; + iconImageUrl -> { + if(mContext != null && getItemCount() > 0) { + if(!iconImageUrl.equals("")) { + glide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon)) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + if(resource instanceof Animatable) { + //This is a gif + //((Animatable) resource).start(); + ((DataViewHolder) holder).subredditIconGifImageView.startAnimation(); } + return false; + } + }) + .into(((DataViewHolder) holder).subredditIconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((DataViewHolder) holder).subredditIconGifImageView); + } - @Override - public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { - if(resource instanceof Animatable) { - //This is a gif - //((Animatable) resource).start(); - ((DataViewHolder) holder).subredditIconGifImageView.startAnimation(); - } - return false; - } - }) - .into(((DataViewHolder) holder).subredditIconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((DataViewHolder) holder).subredditIconGifImageView); - } - - if(holder.getAdapterPosition() >= 0) { - post.setSubredditIconUrl(iconImageUrl); - } + if(holder.getAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconImageUrl); } } }).execute(); @@ -341,21 +340,18 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).typeTextView.setText("VIDEO"); 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, 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); - } - mContext.startActivity(intent); + ((DataViewHolder) holder).imageView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewVideoActivity.class); + intent.setData(videoUri); + intent.putExtra(ViewVideoActivity.TITLE_KEY, title); + 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); } + mContext.startActivity(intent); }); break; case Post.NO_PREVIEW_LINK_TYPE: @@ -507,36 +503,6 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo } }); } - } else if(holder instanceof LoadingViewHolder) { - ((LoadingViewHolder) holder).retryButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - //mPaginationSynchronizer.getPaginationRetryNotifier().retry(); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); - } - }); - - PaginationNotifier mPaginationNotifier = new PaginationNotifier() { - @Override - public void LoadMorePostSuccess() { - isLoadingMorePostSuccess = true; - } - - @Override - public void LoadMorePostFail() { - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - isLoadingMorePostSuccess = false; - } - }; - - /*mPaginationSynchronizer.setPaginationNotifier(mPaginationNotifier); - - if(!mPaginationSynchronizer.isLoadingMorePostsSuccess()) { - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - }*/ } } @@ -575,25 +541,42 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo @Override public int getItemViewType(int position) { - return (position >= getItemCount() ? VIEW_TYPE_LOADING : VIEW_TYPE_DATA); + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + return VIEW_TYPE_DATA; + } + } + + @Override + public int getItemCount() { + if(hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); } private boolean hasExtraRow() { - return networkState != null && networkState != NetworkState.LOADED; + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; } - public void setNetworkState(NetworkState newNetworkState) { + void setNetworkState(NetworkState newNetworkState) { NetworkState previousState = this.networkState; boolean previousExtraRow = hasExtraRow(); this.networkState = newNetworkState; boolean newExtraRow = hasExtraRow(); if (previousExtraRow != newExtraRow) { if (previousExtraRow) { - notifyItemRemoved(getItemCount()); + notifyItemRemoved(super.getItemCount()); } else { - notifyItemInserted(getItemCount()); + notifyItemInserted(super.getItemCount()); } - } else if (newExtraRow && previousState != newNetworkState) { + } else if (newExtraRow && !previousState.equals(newNetworkState)) { notifyItemChanged(getItemCount() - 1); } } @@ -626,12 +609,21 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo } } - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_footer_progress_bar_item) ProgressBar progressBar; + class ErrorViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.relative_layout_footer_progress_bar_item) RelativeLayout relativeLayout; @BindView(R.id.retry_button_footer_progress_bar_item) Button retryButton; - LoadingViewHolder(View itemView) { + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + retryButton.setOnClickListener(view -> retryLoadingMoreCallback.retryLoadingMore()); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_footer_progress_bar_item) ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); } @@ -660,14 +652,6 @@ class PostRecyclerViewAdapter extends PagedListAdapter<Post, RecyclerView.ViewHo ((DataViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); ((DataViewHolder) holder).upvoteButton.clearColorFilter(); ((DataViewHolder) holder).downvoteButton.clearColorFilter(); - } else if(holder instanceof LoadingViewHolder) { - if(isLoadingMorePostSuccess) { - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.GONE); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - } else { - ((LoadingViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - ((LoadingViewHolder) holder).progressBar.setVisibility(View.GONE); - } } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java index 474972dc..4906bbad 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostViewModel.java @@ -9,25 +9,22 @@ import android.arch.paging.PagedList; import android.support.annotation.NonNull; import java.util.Locale; -import java.util.concurrent.Executor; import retrofit2.Retrofit; public class PostViewModel extends ViewModel { - private Executor executor; - private LiveData<NetworkState> networkState; + private PostDataSource postDataSource; + private LiveData<NetworkState> paginationNetworkState; private LiveData<NetworkState> initialLoadingState; private LiveData<PagedList<Post>> posts; public PostViewModel(Retrofit retrofit, String accessToken, Locale locale, boolean isBestPost) { - //executor = Executors.newFixedThreadPool(5); - PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, locale, isBestPost); - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(), - dataSource -> dataSource.getInitialLoading()); - networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(), - dataSource -> dataSource.getNetworkState()); + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + dataSource -> dataSource.getInitialLoadStateLiveData()); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + dataSource -> dataSource.getPaginationNetworkStateLiveData()); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) .setEnablePlaceholders(false) @@ -35,17 +32,16 @@ public class PostViewModel extends ViewModel { .build(); posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + postDataSource = postDataSourceFactory.getPostDataSource(); } public PostViewModel(Retrofit retrofit, Locale locale, boolean isBestPost, String subredditName) { - //executor = Executors.newFixedThreadPool(5); - PostDataSourceFactory postDataSourceFactory = new PostDataSourceFactory(retrofit, locale, isBestPost, subredditName); - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(), - dataSource -> dataSource.getInitialLoading()); - networkState = Transformations.switchMap(postDataSourceFactory.getMutableLiveData(), - dataSource -> dataSource.getNetworkState()); + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + dataSource -> dataSource.getInitialLoadStateLiveData()); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + dataSource -> dataSource.getPaginationNetworkStateLiveData()); PagedList.Config pagedListConfig = (new PagedList.Config.Builder()) @@ -54,20 +50,29 @@ public class PostViewModel extends ViewModel { .build(); posts = (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + postDataSource = postDataSourceFactory.getPostDataSource(); } LiveData<PagedList<Post>> getPosts() { return posts; } - LiveData<NetworkState> getNetworkState() { - return networkState; + LiveData<NetworkState> getPaginationNetworkState() { + return paginationNetworkState; } public LiveData<NetworkState> getInitialLoadingState() { return initialLoadingState; } + void retry() { + postDataSource.retry(); + } + + void retryLoadingMore() { + postDataSource.retryLoadingMore(); + } + public static class Factory extends ViewModelProvider.NewInstanceFactory { private Retrofit retrofit; private String accessToken; diff --git a/app/src/main/res/layout/item_footer_error.xml b/app/src/main/res/layout/item_footer_error.xml new file mode 100644 index 00000000..bd653604 --- /dev/null +++ b/app/src/main/res/layout/item_footer_error.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/relative_layout_footer_progress_bar_item" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_centerVertical="true" + android:layout_toStartOf="@id/retry_button_footer_progress_bar_item" + android:text="@string/load_data_failed" + android:textSize="18sp" /> + + <Button + android:id="@+id/retry_button_footer_progress_bar_item" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:text="@string/retry" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_footer_loading.xml b/app/src/main/res/layout/item_footer_loading.xml new file mode 100644 index 00000000..7cd0d8f2 --- /dev/null +++ b/app/src/main/res/layout/item_footer_loading.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ProgressBar + android:id="@+id/progress_bar_footer_progress_bar_item" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="16dp" + android:layout_centerHorizontal="true" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_footer_progress_bar.xml b/app/src/main/res/layout/item_footer_progress_bar.xml deleted file mode 100644 index 270fc6ef..00000000 --- a/app/src/main/res/layout/item_footer_progress_bar.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/linear_layout_footer_progress_bar_item" - android:orientation="vertical"> - - <ProgressBar - android:id="@+id/progress_bar_footer_progress_bar_item" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginBottom="16dp" - android:layout_gravity="center" /> - - <RelativeLayout - android:id="@+id/relative_layout_footer_progress_bar_item" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginBottom="16dp" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:visibility="gone"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toStartOf="@id/retry_button_footer_progress_bar_item" - android:layout_alignParentStart="true" - android:text="@string/load_data_failed" - android:textSize="18sp" - android:layout_centerVertical="true" /> - - <Button - android:id="@+id/retry_button_footer_progress_bar_item" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentEnd="true" - android:layout_centerVertical="true" - android:background="@color/colorAccent" - android:text="@string/retry" /> - - </RelativeLayout> - -</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/menu/main_activity.xml b/app/src/main/res/menu/main_activity.xml index ed6a2e33..2be22f5f 100644 --- a/app/src/main/res/menu/main_activity.xml +++ b/app/src/main/res/menu/main_activity.xml @@ -8,5 +8,5 @@ android:orderInCategory="1" android:title="@string/action_refresh" android:icon="@drawable/ic_refresh_white_24dp" - app:showAsAction="always" /> + app:showAsAction="never" /> </menu>
\ No newline at end of file |