package com.badoo.chateau.ui.conversations.list; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import com.badoo.barf.mvp.BaseRxPresenter; import com.badoo.barf.rx.ScheduleOn; import com.badoo.chateau.core.model.Conversation; import com.badoo.chateau.core.repos.conversations.ConversationDataSource.LoadResult; import com.badoo.chateau.core.usecases.conversations.DeleteConversations; import com.badoo.chateau.core.usecases.conversations.LoadConversations; import com.badoo.chateau.core.usecases.conversations.SubscribeToConversationUpdates; import java.util.ArrayList; import java.util.List; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; public class BaseConversationListPresenter<C extends Conversation> extends BaseRxPresenter implements ConversationListPresenter<C> { private static final String TAG = BaseConversationListPresenter.class.getSimpleName(); private static final boolean DEBUG = true; @NonNull private final ConversationListView<C> mView; @NonNull private final ConversationListFlowListener<C> mFlowListener; @NonNull private final LoadConversations<C> mLoadConversations; @NonNull private final SubscribeToConversationUpdates mSubscribeToConversationUpdates; @NonNull private final DeleteConversations mDeleteConversations; @Nullable private LoadResult<C> mLastLoadResult; public BaseConversationListPresenter(@NonNull ConversationListView<C> view, @NonNull ConversationListFlowListener<C> flowListener, @NonNull LoadConversations<C> loadConversations, @NonNull SubscribeToConversationUpdates subscribeToConversationUpdates, @NonNull DeleteConversations deleteConversations) { mView = view; mFlowListener = flowListener; mLoadConversations = loadConversations; mSubscribeToConversationUpdates = subscribeToConversationUpdates; mDeleteConversations = deleteConversations; } @Override public void onStart() { super.onStart(); // Setup subscriptions for updates to the list manage(mSubscribeToConversationUpdates.execute() .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> loadNewerConversations(), this::onFatalError)); // Request data reloadConversations(); } @Override public void onConversationClicked(@NonNull C conversation) { mFlowListener.requestOpenConversation(conversation); } @Override public void onDeleteConversations(@NonNull List<C> conversations) { Subscription sub = mDeleteConversations.execute(new ArrayList<>(conversations)) .observeOn(AndroidSchedulers.mainThread()).subscribe(); manage(sub); } @Override public void onMoreConversationsRequired() { if (mLastLoadResult != null && mLastLoadResult.canMoveBackwards()) { loadOlderConversations(); } } protected void reloadConversations() { loadConversations(mLoadConversations.all()); } protected void loadOlderConversations() { loadConversations(mLoadConversations.older()); } protected void loadNewerConversations() { loadConversations(mLoadConversations.newer()); } private void loadConversations(@NonNull Observable<LoadResult<C>> o) { mLastLoadResult = null; manage(o .compose(ScheduleOn.io()) .subscribe(this::onConversationsLoaded, this::onFatalError)); } /** * By default displays the current conversations in the view, this method can be updated to modify the conversations list before it is * shown, can be used to filter the list or augment it */ protected void onShowConversations(@NonNull List<C> conversations) { if (DEBUG) { Log.d(TAG, "Showing " + conversations.size() + " conversations"); } mView.showConversations(new ArrayList<>(conversations)); // Create a new list to avoid issues with the immutable list emitted by the observable } /** * Display a fatal error */ protected void onFatalError(Throwable throwable) { Log.e(TAG, "Fatal error", throwable); mView.showError(true, throwable); } private void onConversationsLoaded(LoadResult<C> result) { if (DEBUG) { Log.d(TAG, "Loaded conversations, moveForward:" + result.canMoveForwards()); } mLastLoadResult = result; onShowConversations(result.getConversations()); if (result.canMoveForwards()) { loadNewerConversations(); } } }