package com.leavjenn.hews.ui.comment; import android.os.Bundle; import android.support.annotation.NonNull; import android.util.Log; import com.leavjenn.hews.Constants; import com.leavjenn.hews.R; import com.leavjenn.hews.data.local.LocalContract; import com.leavjenn.hews.data.local.LocalDataManager; import com.leavjenn.hews.ui.BasePresenter; import com.leavjenn.hews.misc.SharedPrefsContract; import com.leavjenn.hews.misc.UtilsContract; import com.leavjenn.hews.model.Comment; import com.leavjenn.hews.model.Post; import com.leavjenn.hews.data.remote.DataManager; import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult; import com.pushtorefresh.storio.sqlite.operations.put.PutResult; import com.pushtorefresh.storio.sqlite.operations.put.PutResults; import org.parceler.Parcels; import java.util.ArrayList; import java.util.List; import rx.Observable; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; public class CommentPresenter extends BasePresenter { public static final String TAG = "CommentPresenter"; public static final String KEY_POST_PARCEL = "arg_post_parcel"; public static final String KEY_IS_BOOKMARKED = "arg_is_bookmarked"; public static final String KEY_POST_ID = "arg_post_id"; public static final String KEY_IS_COMMENTS_LOADING_COMPLETED = "arg_is_fetch_completed"; public static final String KEY_COMMENTS_PARCEL = "arg_comments_parcel"; private CommentView mCommentView; private DataManager mDataManager; private LocalContract mLocalDataManager; private SharedPrefsContract mPrefsManager; private UtilsContract mUtils; private boolean mIsBookmarked, isCommentsLoadingCompleted; private Post mPost; private long mPostId; private List<Comment> mCachedCommentList; private Observable<List<Comment>> mCommentListObservable; private CompositeSubscription mCompositeSubscription; public CommentPresenter(@NonNull CommentView commentView) { mCommentView = commentView; mCompositeSubscription = new CompositeSubscription(); mCachedCommentList = new ArrayList<>(); } public CommentPresenter(@NonNull CommentView commentView, @NonNull DataManager dataManager, @NonNull LocalContract localDataManager, @NonNull SharedPrefsContract prefsManager, @NonNull UtilsContract utils) { this(commentView); mDataManager = dataManager; mLocalDataManager = localDataManager; mPrefsManager = prefsManager; mCompositeSubscription = new CompositeSubscription(); mUtils = utils; } public void setView(CommentView commentView) { mCommentView = commentView; } public void setDataManager(DataManager dataManager) { mDataManager = dataManager; } public void setLocalDataManager(LocalDataManager localDataManager) { mLocalDataManager = localDataManager; } public void setPrefsManager(SharedPrefsContract sharedPrefsContract) { mPrefsManager = sharedPrefsContract; } public void setUtils(UtilsContract utils) { mUtils = utils; } public void setPost(Post post) { mPost = post; } public void setPostId(long postId) { mPostId = postId; } public void setBookmarkState(boolean isBookmarked) { mIsBookmarked = isBookmarked; } @Override public void setup() { if (mPost == null) { mCommentView.showInfoLog(TAG + ":setup", "null post"); refresh(); } else { mCommentView.showFooter(); mCommentView.showHeader(mPost); if (mIsBookmarked) { if (mPrefsManager.areCommentsBookmarked(mPost.getId())) { mCommentView.showInfoLog(TAG + ":setup", "get db comment"); getCommentsFromDb(mPost); } else { // post kid list is not stored, get from getPost() refresh(); } } else if (isCommentsLoadingCompleted) { mCommentView.showInfoLog(TAG + ":setup", "get cached comment"); mCommentView.restoreCachedComments(mCachedCommentList); mCommentView.updateListFooter(Constants.LOADING_FINISH); } else { mCommentView.showInfoLog(TAG + ":setup", "get comment"); getComments(mPost, mCommentListObservable == null); } } } @Override public void restoreState(Bundle savedInstanceState) { if (savedInstanceState == null) { return; } mPostId = savedInstanceState.getLong(KEY_POST_ID); mPost = Parcels.unwrap(savedInstanceState.getParcelable(KEY_POST_PARCEL)); mIsBookmarked = savedInstanceState.getBoolean(KEY_IS_BOOKMARKED); isCommentsLoadingCompleted = savedInstanceState.getBoolean(KEY_IS_COMMENTS_LOADING_COMPLETED); if (isCommentsLoadingCompleted) { mCachedCommentList = ((ArrayList<Comment>) Parcels.unwrap( savedInstanceState.getParcelable(KEY_COMMENTS_PARCEL))); } } @Override public void saveState(Bundle outState) { outState.putLong(KEY_POST_ID, mPostId); outState.putParcelable(KEY_POST_PARCEL, Parcels.wrap(mPost)); outState.putBoolean(KEY_IS_BOOKMARKED, mIsBookmarked); outState.putBoolean(KEY_IS_COMMENTS_LOADING_COMPLETED, isCommentsLoadingCompleted); if (isCommentsLoadingCompleted) { outState.putParcelable(KEY_COMMENTS_PARCEL, Parcels.wrap(mCachedCommentList)); } } @Override public void destroy() { // if (mCompositeSubscription.hasSubscriptions()) { mCompositeSubscription.clear(); // } mCommentView.showInfoLog(TAG, "destroy"); mCommentView = null; mDataManager = null; mLocalDataManager = null; mPrefsManager = null; mUtils = null; } @Override public void unsubscribe() { mCompositeSubscription.clear(); } public void refresh() { if (!mUtils.isOnline()) { mCommentView.hideSwipeRefresh(); mCommentView.showOfflineSnackBar(); return; } isCommentsLoadingCompleted = false; mCompositeSubscription.clear(); mCachedCommentList.clear(); mCommentView.showSwipeRefresh(); mCommentView.hideOfflineSnackBar(); mCommentView.clearAdapter(); getPost(mPost != null ? mPost.getId() : mPostId); } public void getPost(long postId) { mCompositeSubscription.add(mDataManager.getPost(postId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Post>() { @Override public void call(Post post) { mCommentView.hideSwipeRefresh(); mCommentView.showFooter(); mCommentView.updateListFooter(Constants.LOADING_IN_PROGRESS); mPost = post; mCommentView.showHeader(mPost); getComments(mPost, true); mCommentView.setToolbarUrl(mPost.getUrl()); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { mCommentView.showErrorLog("getPost", throwable.toString()); } })); } public void getComments(final Post post, final boolean updateObservable) { if (!mUtils.isOnline()) { mCommentView.showOfflineSnackBarForShowComments(post, updateObservable); mCommentView.updateListFooter(Constants.LOADING_ERROR); return; } Log.i("getComments", "kids:" + String.valueOf(post.getKids())); if (post.getKids() != null && !post.getKids().isEmpty()) { if (updateObservable || mCommentListObservable == null) { mCommentListObservable = mDataManager.getComments(post, 0).cache(); Log.i("getComments", "updateObservable"); } mCompositeSubscription.add(mCommentListObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<Comment>>() { @Override public void onCompleted() { mCommentView.updateListFooter(Constants.LOADING_FINISH); for (int i = 0; i < mCommentView.getCommentsCount(); i++) { Comment comment = mCommentView.getComment(i); comment.setParent(post.getId()); comment.setIndex(i); } isCommentsLoadingCompleted = true; mCachedCommentList = mCommentView.getAllComments(); // if (SharedPrefsManager.isPostBookmarked(prefs, post.getId())) { if (mPrefsManager.isPostBookmarked(post.getId())) { // putCommentsToDb(mCommentAdapter.getCommentList()); putCommentsToDb(mCommentView.getAllComments()); } } @Override public void onError(Throwable e) { mCommentView.updateListFooter(Constants.LOADING_ERROR); mCommentView.showLongToast(R.string.prompt_comments_loading_error); mCommentView.showErrorLog("getComments", e.toString()); } @Override public void onNext(List<Comment> commentList) { mCommentView.showComments(commentList); } }) ); } else { mCommentView.updateListFooter(Constants.LOADING_PROMPT_NO_CONTENT); } } private void getCommentsFromDb(Post post) { mCompositeSubscription.add( mLocalDataManager.getStoryCommentsFromDb(post.getId()) // mDataManager.getStoryCommentsFromDb(getActivity(), post.getId()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Comment>>() { @Override public void call(List<Comment> comments) { mCommentView.showComments(comments); mCommentView.updateListFooter(Constants.LOADING_FINISH); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { mCommentView.updateListFooter(Constants.LOADING_ERROR); mCommentView.showErrorLog("getCommentFromDb", throwable.toString()); } })); } public void addBookmark() { putPostToDb(mPost); } public void removeBookmark() { deletePostAndCommentFromDb(); } private void putPostToDb(Post post) { mCompositeSubscription.add( mLocalDataManager.putPostToDb(post) // mDataManager.putPostToDb(getActivity(), post) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<PutResult>() { @Override public void call(PutResult putResult) { mCommentView.showBookmarkSuccessSnackBar(); // SharedPrefsManager.setPostBookmarked(prefs, mPost.getId()); mPrefsManager.setPostBookmarked(mPost.getId()); if (isCommentsLoadingCompleted) { putCommentsToDb(mCommentView.getAllComments()); } } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { mCommentView.showErrorLog("putPostToDb", throwable.toString()); } })); } private void putCommentsToDb(List<Comment> comments) { mCompositeSubscription.add( mLocalDataManager.putCommentsToDb(comments) // mDataManager.putCommentsToDb(getActivity(), comments) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<PutResults<Comment>>() { @Override public void call(PutResults<Comment> commentPutResults) { // SharedPrefsManager.setCommentsBookmarked(prefs, mPost.getId()); mPrefsManager.setCommentsBookmarked(mPost.getId()); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { mCommentView.showErrorLog("putCommentsToDb", throwable.toString()); } })); } private void deletePostAndCommentFromDb() { mCompositeSubscription.add(Observable.merge( mLocalDataManager.deletePostFromDb(mPost), mLocalDataManager.deleteStoryCommentsFromDb(mPost.getId()) // mDataManager.deletePostFromDb(getActivity(), mPost), // mDataManager.deleteStoryCommentsFromDb(getActivity(), mPost.getId()) ) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<DeleteResult>() { @Override public void onCompleted() { mCommentView.showUnbookmarkSuccessSnackBar(); // SharedPrefsManager.setPostUnbookmarked(prefs, mPost.getId()); mPrefsManager.setPostUnbookmarked(mPost.getId()); // SharedPrefsManager.setCommentsUnbookmarked(prefs, mPost.getId()); mPrefsManager.setCommentsUnbookmarked(mPost.getId()); } @Override public void onError(Throwable e) { mCommentView.showErrorLog("delPost&CommentFromDb", e.toString()); } @Override public void onNext(DeleteResult deleteResult) { mCommentView.showInfoLog(deleteResult.affectedTables().toString(), String.valueOf(deleteResult.numberOfRowsDeleted())); } })); } }