package com.kickstarter.viewmodels;
import android.support.annotation.NonNull;
import com.kickstarter.libs.ActivityViewModel;
import com.kickstarter.libs.ApiPaginator;
import com.kickstarter.libs.CurrentUserType;
import com.kickstarter.libs.Environment;
import com.kickstarter.libs.utils.IntegerUtils;
import com.kickstarter.libs.utils.NumberUtils;
import com.kickstarter.models.MessageThread;
import com.kickstarter.models.User;
import com.kickstarter.services.ApiClientType;
import com.kickstarter.services.apiresponses.MessageThreadsEnvelope;
import com.kickstarter.ui.activities.MessageThreadsActivity;
import java.util.List;
import rx.Observable;
import rx.subjects.PublishSubject;
import static com.kickstarter.libs.rx.transformers.Transformers.coalesce;
import static com.kickstarter.libs.rx.transformers.Transformers.neverError;
public interface MessageThreadsViewModel {
interface Inputs {
/** Invoke when pagination should happen. */
void nextPage();
/** Call when the swipe refresher is invoked. */
void refresh();
}
interface Outputs {
/** Emits a boolean indicating whether message threads are being fetched from the API. */
Observable<Boolean> isFetchingMessageThreads();
/** Emits a list of message threads to be displayed. */
Observable<List<MessageThread>> messageThreads();
/** Emits a boolean to determine if the unread count text view should be hidden. */
Observable<Boolean> unreadCountTextViewHidden();
/** Emits the unread message count to be displayed. */
Observable<String> unreadCountTextViewText();
}
final class ViewModel extends ActivityViewModel<MessageThreadsActivity> implements Inputs, Outputs {
private final ApiClientType client;
private final CurrentUserType currentUser;
public ViewModel(final @NonNull Environment environment) {
super(environment);
this.client = environment.apiClient();
this.currentUser = environment.currentUser();
final Observable<User> freshUser = this.client.fetchCurrentUser()
.retry(2)
.compose(neverError());
freshUser.subscribe(this.currentUser::refresh);
final ApiPaginator<MessageThread, MessageThreadsEnvelope, Void> paginator =
ApiPaginator.<MessageThread, MessageThreadsEnvelope, Void>builder()
.nextPage(this.nextPage)
.envelopeToListOfData(MessageThreadsEnvelope::messageThreads)
.envelopeToMoreUrl(env -> env.urls().api().moreMessageThreads())
.loadWithParams(__ -> this.client.fetchMessageThreads())
.loadWithPaginationPath(this.client::fetchMessageThreadsWithPaginationPath)
.build();
this.isFetchingMessageThreads = paginator.isFetching();
this.messageThreads = paginator.paginatedData();
this.startMessagesActivity = this.messageThreadClicked;
final Observable<Integer> unreadMessagesCount = this.currentUser.loggedInUser()
.map(User::unreadMessagesCount)
.compose(coalesce(0));
this.unreadCountTextViewHidden = unreadMessagesCount.map(IntegerUtils::isZero);
this.unreadCountTextViewText = unreadMessagesCount.map(NumberUtils::format);
}
private final PublishSubject<Void> messageThreadClicked = PublishSubject.create();
private final PublishSubject<Void> nextPage = PublishSubject.create();
private final PublishSubject<Void> refresh = PublishSubject.create();
private final Observable<Boolean> isFetchingMessageThreads;
private final Observable<List<MessageThread>> messageThreads;
private final Observable<Void> startMessagesActivity;
private final Observable<Boolean> unreadCountTextViewHidden;
private final Observable<String> unreadCountTextViewText;
public final Inputs inputs = this;
public final Outputs outputs = this;
@Override public void nextPage() {
this.nextPage.onNext(null);
}
@Override public void refresh() {
this.refresh.onNext(null);
}
@Override public @NonNull Observable<Boolean> isFetchingMessageThreads() {
return this.isFetchingMessageThreads;
}
@Override public @NonNull Observable<List<MessageThread>> messageThreads() {
return this.messageThreads;
}
@Override public @NonNull Observable<Boolean> unreadCountTextViewHidden() {
return this.unreadCountTextViewHidden;
}
@Override public @NonNull Observable<String> unreadCountTextViewText() {
return this.unreadCountTextViewText;
}
}
}