Last active
December 30, 2017 17:33
-
-
Save Augusent/ed8c77bd3da48b5e9c34c1b325c514c5 to your computer and use it in GitHub Desktop.
MVI large reducer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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