Skip to content

Instantly share code, notes, and snippets.

@Augusent
Last active December 30, 2017 17:33
Show Gist options
  • Save Augusent/ed8c77bd3da48b5e9c34c1b325c514c5 to your computer and use it in GitHub Desktop.
Save Augusent/ed8c77bd3da48b5e9c34c1b325c514c5 to your computer and use it in GitHub Desktop.
MVI large reducer
public class TicketsPresenter extends BasePresenter<TicketsView, TicketsModel> {
private final DisplayErrorUsecase displayErrorUsecase;
private final LoadTicketsPageUsecase loadTicketsPageUsecase;
private final ArchiveTicketUsecase archiveTicketUsecase;
private final RenewTicketUsecase renewTicketUsecase;
private final DeleteTicketUsecase deleteTicketUsecase;
private final DeleteAllArchivedTicketsUsecase deleteAllArchivedTicketsUsecase;
@Inject TicketsPresenter(DisplayErrorUsecase displayErrorUsecase,
LoadTicketsPageUsecase loadTicketsPageUsecase,
ArchiveTicketUsecase archiveTicketUsecase,
RenewTicketUsecase renewTicketUsecase,
DeleteTicketUsecase deleteTicketUsecase,
DeleteAllArchivedTicketsUsecase deleteAllArchivedTicketsUsecase) {
this.displayErrorUsecase = displayErrorUsecase;
this.loadTicketsPageUsecase = loadTicketsPageUsecase;
this.archiveTicketUsecase = archiveTicketUsecase;
this.renewTicketUsecase = renewTicketUsecase;
this.deleteTicketUsecase = deleteTicketUsecase;
this.deleteAllArchivedTicketsUsecase = deleteAllArchivedTicketsUsecase;
}
@Override protected void bindIntents() {
final Observable<Result> allIntents = Observable.merge(Arrays.asList(
intent(TicketsView::displayErrorActions).compose(displayErrorUsecase),
intent(TicketsView::loadFirstPageSignal).compose(loadTicketsPageUsecase),
intent(TicketsView::loadFreshPageSignal).compose(loadTicketsPageUsecase),
intent(TicketsView::loadNextPageSignal).compose(loadTicketsPageUsecase),
intent(TicketsView::archiveTicket).compose(archiveTicketUsecase),
intent(TicketsView::renewTicket).compose(renewTicketUsecase),
intent(TicketsView::deleteTicket).compose(deleteTicketUsecase),
intent(TicketsView::deleteAllArchivedTicketsSignal).compose(deleteAllArchivedTicketsUsecase)
));
final Observable<TicketsModel> modelObservable = allIntents
.scan(TicketsModel.builder().build(), this::reduceModel)
.doOnNext(model -> Timber.v("render: %s", model))
.observeOn(AndroidSchedulers.mainThread());
subscribeViewState(modelObservable, TicketsView::render);
}
@Override protected TicketsModel reduceModel(TicketsModel model, Result result) {
final TicketsModel.Builder builder = model.toBuilder();
if (result instanceof DisplayErrorUsecase.Result) {
return builder
.error(null)
.build();
}
if (result instanceof LoadTicketsPageUsecase.Result) {
final LoadTicketsPageUsecase.Result res = (LoadTicketsPageUsecase.Result) result;
switch (res.status()) {
case INITIAL_PAGE:
if (res.success()) builder.items(res.data());
return builder
.firstPageLoading(res.loading())
.firstPageError(res.error())
.build();
case REFRESH_PAGE:
if (res.success()) builder.items(res.data());
return builder
.freshPageLoading(res.loading())
.freshPageError(res.error())
.build();
case NEXT_PAGE:
if (res.success()) {
final List<ItemViewModel> data = new ArrayList<>();
data.addAll(model.items());
data.addAll(res.data());
builder.items(data);
}
return builder
.nextPageLoading(res.loading())
.nextPageError(res.error())
.build();
}
}
if (result instanceof ArchiveTicketUsecase.Result || result instanceof DeleteTicketUsecase.Result) {
//noinspection unchecked
final LceResult<Ticket> res = ((LceResult) result);
if (res.success()) {
final List<ItemViewModel> data = new ArrayList<>(model.items());
data.remove(new TicketItemViewModel(res.data()));
builder.items(data);
}
return builder
.loading(res.loading())
.error(res.error())
.build();
}
if (result instanceof RenewTicketUsecase.Result) {
final RenewTicketUsecase.Result res = (RenewTicketUsecase.Result) result;
if (res.success()) {
final List<ItemViewModel> data = new ArrayList<>(model.items());
data.remove(new TicketItemViewModel(res.oldTicket()));
builder.items(data);
}
return builder
.loading(res.loading())
.error(res.error())
.build();
}
if (result instanceof DeleteAllArchivedTicketsUsecase.Result) {
final DeleteAllArchivedTicketsUsecase.Result res = (DeleteAllArchivedTicketsUsecase.Result) result;
if (res.success()) builder.items(Collections.emptyList());
return builder
.error(res.error())
.loading(res.loading())
.build();
}
throw new IllegalStateException("Can not reduce model for result " + result.getClass().getName());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment