From 4338dbd2774925d9ecbe6a29616d330d5f2602a2 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Mon, 8 Jul 2019 23:54:54 +0800 Subject: Retain comments after orientation changes in ViewPostDetailActivity. --- .../java/SubredditDatabase/SubredditViewModel.java | 3 +- .../infinityforreddit/CommentDataSource.java | 189 --------------------- .../CommentDataSourceFactory.java | 49 ------ .../CommentRecyclerViewAdapter.java | 4 + .../infinityforreddit/CommentViewModel.java | 90 ---------- .../infinityforreddit/ViewPostDetailActivity.java | 31 +++- 6 files changed, 33 insertions(+), 333 deletions(-) delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java (limited to 'app/src/main') diff --git a/app/src/main/java/SubredditDatabase/SubredditViewModel.java b/app/src/main/java/SubredditDatabase/SubredditViewModel.java index a0dfa7c9..8899abdd 100644 --- a/app/src/main/java/SubredditDatabase/SubredditViewModel.java +++ b/app/src/main/java/SubredditDatabase/SubredditViewModel.java @@ -37,8 +37,9 @@ public class SubredditViewModel extends AndroidViewModel { this.subredditName = subredditName; } + @NonNull @Override - public T create(Class modelClass) { + public T create(@NonNull Class modelClass) { //noinspection unchecked return (T) new SubredditViewModel(mApplication, subredditName); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java deleted file mode 100644 index 0e664ea2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSource.java +++ /dev/null @@ -1,189 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import java.util.Locale; - -import retrofit2.Retrofit; - -public class CommentDataSource extends PageKeyedDataSource { - interface OnCommentFetchedCallback { - void hasComment(); - void noComment(); - } - - private Retrofit retrofit; - private Locale locale; - private String subredditNamePrefixed; - private String article; - private String comment; - private boolean isPost; - private OnCommentFetchedCallback onCommentFetchedCallback; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - - private LoadInitialParams initialParams; - private LoadInitialCallback initialCallback; - private LoadParams params; - private LoadCallback callback; - - private String mParentId; - - CommentDataSource(Retrofit retrofit, Locale locale, String subredditNamePrefixed, String article, - String comment, boolean isPost, OnCommentFetchedCallback onCommentFetchedCallback) { - this.retrofit = retrofit; - this.locale = locale; - this.subredditNamePrefixed = subredditNamePrefixed; - this.article = article; - this.comment = comment; - this.isPost = isPost; - paginationNetworkStateLiveData = new MutableLiveData(); - initialLoadStateLiveData = new MutableLiveData(); - this.onCommentFetchedCallback = onCommentFetchedCallback; - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { - initialParams = params; - initialCallback = callback; - - initialLoadStateLiveData.postValue(NetworkState.LOADING); - - RedditAPI api = retrofit.create(RedditAPI.class); - - //Call comments = api.getComments(subredditNamePrefixed, article, comment); - /*comments.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if(response.isSuccessful()) { - ParseComment.parseComment(response.body(), new ArrayList<>(), locale, isPost, - 0, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(List commentData, String parentId, - String commaSeparatedChildren) { - if(commentData.size() > 0) { - onCommentFetchedCallback.hasComment(); - mParentId = parentId; - } else { - onCommentFetchedCallback.noComment(); - } - - callback.onResult((List) commentData, null, commaSeparatedChildren); - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParseCommentFailed() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing comment")); - } - }); - } else { - Log.i("comment call failed", response.message()); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing comment")); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching comment")); - } - });*/ - } - - @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { - this.params = params; - this.callback = callback; - - if(params.key.equals("null") || params.key.equals("")) { - return; - } - - paginationNetworkStateLiveData.postValue(NetworkState.LOADING); - - RedditAPI api = retrofit.create(RedditAPI.class); - - //Call moreChildrenBasicInfo = api.getMoreChildren(mParentId, params.key); - /*moreChildrenBasicInfo.enqueue(new Callback() { - @Override - public void onResponse(Call call, Response response) { - if(response.isSuccessful()) { - ParseComment.parseMoreCommentBasicInfo(response.body(), new ParseComment.ParseMoreCommentBasicInfoListener() { - @Override - public void onParseMoreCommentBasicInfoSuccess(String commaSeparatedChildrenId) { - Call moreComments = api.getInfo(subredditNamePrefixed, commaSeparatedChildrenId); - moreComments.enqueue(new Callback() { - @Override - public void onResponse(Call call, Response response) { - if(response.isSuccessful()) { - ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, - 0, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(List commentData, String parentId, - String commaSeparatedChildren) { - callback.onResult((List) commentData, null); - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParseCommentFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - Log.i("comment call failed", response.message()); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - @Override - public void onParseMoreCommentBasicInfoFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Parse more comments basic info failed")); - } - }); - } else { - Log.i("comment call failed", response.message()); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(Call call, Throwable t) { - String errorMessage = t == null ? "unknown error" : t.getMessage(); - 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/CommentDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java deleted file mode 100644 index 1d16e2d2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentDataSourceFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import java.util.Locale; - -import retrofit2.Retrofit; - -public class CommentDataSourceFactory extends DataSource.Factory { - private Retrofit retrofit; - private Locale locale; - private String subredditNamePrefixed; - private String article; - private String comment; - private boolean isPost; - private CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback; - - private CommentDataSource commentDataSource; - private MutableLiveData commentDataSourceMutableLiveData; - - CommentDataSourceFactory(Retrofit retrofit, Locale locale, String subredditNamePrefixed, - String article, String comment, boolean isPost, - CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { - this.retrofit = retrofit; - this.locale = locale; - this.subredditNamePrefixed = subredditNamePrefixed; - this.article = article; - this.comment = comment; - this.isPost = isPost; - commentDataSourceMutableLiveData = new MutableLiveData<>(); - this.onCommentFetchedCallback = onCommentFetchedCallback; - } - - @Override - public DataSource create() { - commentDataSource = new CommentDataSource(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); - commentDataSourceMutableLiveData.postValue(commentDataSource); - return commentDataSource; - } - - public MutableLiveData getCommentDataSourceMutableLiveData() { - return commentDataSourceMutableLiveData; - } - - CommentDataSource getCommentDataSource() { - return commentDataSource; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java index b72ec28e..b7ebf9c1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentRecyclerViewAdapter.java @@ -604,6 +604,10 @@ class CommentRecyclerViewAdapter extends RecyclerView.Adapter getVisibleComments() { + return mVisibleComments; + } + @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { if (holder instanceof CommentViewHolder) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java deleted file mode 100644 index def1e287..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentViewModel.java +++ /dev/null @@ -1,90 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; -import androidx.annotation.NonNull; - -import java.util.Locale; - -import retrofit2.Retrofit; - -public class CommentViewModel extends ViewModel { - private CommentDataSourceFactory commentDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData> comments; - - public CommentViewModel(Retrofit retrofit, Locale locale, String subredditNamePrefixed, - String article, String comment, boolean isPost, - CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { - commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); - - initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceMutableLiveData(), - dataSource -> dataSource.getInitialLoadStateLiveData()); - paginationNetworkState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceMutableLiveData(), - dataSource -> dataSource.getPaginationNetworkStateLiveData()); - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - comments = (new LivePagedListBuilder(commentDataSourceFactory, pagedListConfig)).build(); - } - - LiveData> getComments() { - return comments; - } - - LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - LiveData getInitialLoadingState() { - return initialLoadingState; - } - - void refresh() { - commentDataSourceFactory.getCommentDataSource().invalidate(); - } - - void retry() { - commentDataSourceFactory.getCommentDataSource().retry(); - } - - void retryLoadingMore() { - commentDataSourceFactory.getCommentDataSource().retryLoadingMore(); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private Locale locale; - private String subredditNamePrefixed; - private String article; - private String comment; - private boolean isPost; - private CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback; - - public Factory(Retrofit retrofit, Locale locale, String subredditNamePrefixed, - String article, String comment, boolean isPost, - CommentDataSource.OnCommentFetchedCallback onCommentFetchedCallback) { - this.retrofit = retrofit; - this.locale = locale; - this.subredditNamePrefixed = subredditNamePrefixed; - this.article = article; - this.comment = comment; - this.isPost = isPost; - this.onCommentFetchedCallback = onCommentFetchedCallback; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new CommentViewModel(retrofit, locale, subredditNamePrefixed, article, comment, isPost, onCommentFetchedCallback); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index cf6ae934..96084fc6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -49,6 +49,11 @@ public class ViewPostDetailActivity extends AppCompatActivity { private static final String ORIENTATION_STATE = "OS"; private static final String POST_STATE = "PS"; private static final String IS_REFRESHING_STATE = "IRS"; + private static final String IS_LOADING_MORE_CHILDREN_STATE = "ILMCS"; + private static final String COMMENTS_STATE = "CS"; + private static final String HAS_MORE_CHILDREN_STATE = "HMCS"; + private static final String MORE_CHILDREN_LIST_STATE = "MCLS"; + private static final String MORE_CHILDREN_STARTING_INDEX_STATE = "MCSIS"; private Post mPost; private int postListPosition = -1; @@ -58,6 +63,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { private ArrayList children; private int mChildrenStartingIndex = 0; private boolean loadMoreChildrenSuccess = true; + private boolean hasMoreChildren; private LinearLayoutManager mLinearLayoutManager; private CommentRecyclerViewAdapter mAdapter; @@ -128,14 +134,24 @@ public class ViewPostDetailActivity extends AppCompatActivity { if(isRefreshing) { isRefreshing = false; refresh(); + } else { + mAdapter.addComments(savedInstanceState.getParcelableArrayList(COMMENTS_STATE), + savedInstanceState.getBoolean(HAS_MORE_CHILDREN_STATE)); + isLoadingMoreChildren = savedInstanceState.getBoolean(IS_LOADING_MORE_CHILDREN_STATE); + children = savedInstanceState.getStringArrayList(MORE_CHILDREN_LIST_STATE); + mChildrenStartingIndex = savedInstanceState.getInt(MORE_CHILDREN_STARTING_INDEX_STATE); + if(isLoadingMoreChildren) { + isLoadingMoreChildren = false; + fetchMoreComments(); + } } + } else { + fetchComment(); } if(getIntent().hasExtra(EXTRA_POST_LIST_POSITION)) { postListPosition = getIntent().getExtras().getInt(EXTRA_POST_LIST_POSITION); } - - fetchComment(); } private void fetchComment() { @@ -148,7 +164,8 @@ public class ViewPostDetailActivity extends AppCompatActivity { String parentId, ArrayList children) { ViewPostDetailActivity.this.children = children; - mAdapter.addComments(expandedComments, children.size() != 0); + hasMoreChildren = children.size() != 0; + mAdapter.addComments(expandedComments, hasMoreChildren); if(children.size() > 0) { mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -219,7 +236,8 @@ public class ViewPostDetailActivity extends AppCompatActivity { 0, mLocale, new FetchComment.FetchMoreCommentListener() { @Override public void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex) { - mAdapter.addComments(expandedComments, childrenStartingIndex < children.size()); + hasMoreChildren = childrenStartingIndex < children.size(); + mAdapter.addComments(expandedComments, hasMoreChildren); mChildrenStartingIndex = childrenStartingIndex; isLoadingMoreChildren = false; loadMoreChildrenSuccess = true; @@ -322,6 +340,11 @@ public class ViewPostDetailActivity extends AppCompatActivity { outState.putInt(ORIENTATION_STATE, orientation); outState.putParcelable(POST_STATE, mPost); outState.putBoolean(IS_REFRESHING_STATE, isRefreshing); + outState.putBoolean(IS_LOADING_MORE_CHILDREN_STATE, isLoadingMoreChildren); + outState.putParcelableArrayList(COMMENTS_STATE, mAdapter.getVisibleComments()); + outState.putBoolean(HAS_MORE_CHILDREN_STATE, hasMoreChildren); + outState.putStringArrayList(MORE_CHILDREN_LIST_STATE, children); + outState.putInt(MORE_CHILDREN_STARTING_INDEX_STATE, mChildrenStartingIndex); } @Override -- cgit v1.2.3