package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import com.fastaccess.R; import com.fastaccess.data.dao.AssigneesRequestModel; import com.fastaccess.data.dao.IssueRequestModel; import com.fastaccess.data.dao.LabelListModel; import com.fastaccess.data.dao.LabelModel; import com.fastaccess.data.dao.MergeRequestModel; import com.fastaccess.data.dao.MilestoneModel; import com.fastaccess.data.dao.PullsIssuesParser; import com.fastaccess.data.dao.UsersListModel; import com.fastaccess.data.dao.model.Login; import com.fastaccess.data.dao.model.PullRequest; import com.fastaccess.data.dao.model.User; import com.fastaccess.data.dao.types.IssueState; import com.fastaccess.data.service.IssueService; import com.fastaccess.helper.BundleConstant; import com.fastaccess.helper.InputHelper; import com.fastaccess.helper.RxHelper; import com.fastaccess.provider.rest.RestProvider; import com.fastaccess.ui.base.mvp.presenter.BasePresenter; import com.fastaccess.ui.widgets.SpannableBuilder; import java.util.ArrayList; import retrofit2.Response; import rx.Observable; /** * Created by Kosh on 10 Dec 2016, 9:23 AM */ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View> implements PullRequestPagerMvp.Presenter { private PullRequest pullRequest; private int issueNumber; private String login; private String repoId; private boolean isCollaborator; private boolean showToRepoBtn; @Nullable @Override public PullRequest getPullRequest() { return pullRequest; } @Override public void onError(@NonNull Throwable throwable) { if (RestProvider.getErrorCode(throwable) == 404) { sendToView(PullRequestPagerMvp.View::onFinishActivity); } else { onWorkOffline(); } super.onError(throwable); } @Override public void onActivityCreated(@Nullable Intent intent) { if (intent != null && intent.getExtras() != null) { issueNumber = intent.getExtras().getInt(BundleConstant.ID); login = intent.getExtras().getString(BundleConstant.EXTRA); repoId = intent.getExtras().getString(BundleConstant.EXTRA_TWO); showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE); if (pullRequest != null) { sendToView(PullRequestPagerMvp.View::onSetupIssue); return; } else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) { makeRestCall(RestProvider.getPullRequestService() .getPullRequest(login, repoId, issueNumber) .flatMap(pullRequest1 -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()), (pullRequest1, booleanResponse) -> { isCollaborator = booleanResponse.code() == 204; return pullRequest1; }) .flatMap(pullRequest1 -> RestProvider.getIssueService().getIssue(login, repoId, issueNumber), (pullRequest1, issue) -> {//hack to get reactions from issue api if (issue != null) { pullRequest1.setReactions(issue.getReactions()); } return pullRequest1; }), pullRequestModelResponse -> { pullRequest = pullRequestModelResponse; pullRequest.setRepoId(repoId); pullRequest.setLogin(login); sendToView(PullRequestPagerMvp.View::onSetupIssue); manageSubscription(pullRequest.save(pullRequest).subscribe()); }); return; } } sendToView(PullRequestPagerMvp.View::onSetupIssue); } @Override public void onWorkOffline() { if (pullRequest == null) { manageSubscription(PullRequest.getPullRequestByNumber(issueNumber, repoId, login) .subscribe(pullRequestModel -> { if (pullRequestModel != null) { pullRequest = pullRequestModel; sendToView(PullRequestPagerMvp.View::onSetupIssue); } })); } } @Override public boolean isOwner() { if (getPullRequest() == null) return false; User userModel = getPullRequest() != null ? getPullRequest().getUser() : null; Login me = Login.getUser(); PullsIssuesParser parser = PullsIssuesParser.getForIssue(getPullRequest().getHtmlUrl()); return (userModel != null && userModel.getLogin().equalsIgnoreCase(me.getLogin())) || (parser != null && parser.getLogin().equalsIgnoreCase(me.getLogin())); } @Override public boolean isRepoOwner() { if (getPullRequest() == null) return false; Login me = Login.getUser(); return TextUtils.equals(login, me.getLogin()); } @Override public boolean isLocked() { return getPullRequest() != null && getPullRequest().isLocked(); } @Override public boolean isMergeable() { return getPullRequest() != null && getPullRequest().isMergeable() && !getPullRequest().isMerged(); } @Override public boolean showToRepoBtn() { return showToRepoBtn; } @Override public void onHandleConfirmDialog(@Nullable Bundle bundle) { if (bundle != null) { boolean proceedCloseIssue = bundle.getBoolean(BundleConstant.EXTRA); boolean proceedLockUnlock = bundle.getBoolean(BundleConstant.EXTRA_TWO); if (proceedCloseIssue) { onOpenCloseIssue(); } else if (proceedLockUnlock) { onLockUnlockConversations(); } } } @Override public void onLockUnlockConversations() { PullRequest currentPullRequest = getPullRequest(); if (currentPullRequest == null) return; IssueService service = RestProvider.getIssueService(); Observable<Response<Boolean>> observable = RxHelper .getObserver(isLocked() ? service.unlockIssue(login, repoId, issueNumber) : service.lockIssue(login, repoId, issueNumber)); makeRestCall(observable, booleanResponse -> { int code = booleanResponse.code(); if (code == 204) { pullRequest.setLocked(!isLocked()); sendToView(PullRequestPagerMvp.View::onSetupIssue); } }); } @Override public void onOpenCloseIssue() { if (getPullRequest() != null) { IssueRequestModel requestModel = IssueRequestModel.clone(getPullRequest(), true); manageSubscription(RxHelper.getObserver(RestProvider.getPullRequestService().editPullRequest(login, repoId, issueNumber, requestModel)) .doOnSubscribe(() -> sendToView(view -> view.showProgress(0))) .doOnNext(issue -> { if (issue != null) { sendToView(view -> view.showSuccessIssueActionMsg(getPullRequest().getState() == IssueState.open)); issue.setRepoId(getPullRequest().getRepoId()); issue.setLogin(getPullRequest().getLogin()); pullRequest = issue; sendToView(PullRequestPagerMvp.View::onSetupIssue); } }) .onErrorReturn(throwable -> { sendToView(view -> view.showErrorIssueActionMsg(getPullRequest().getState() == IssueState.open)); return null; }) .subscribe()); } } @NonNull @Override public SpannableBuilder getMergeBy(@NonNull PullRequest pullRequest, @NonNull Context context) { return PullRequest.getMergeBy(pullRequest, context, false); } @Override public void onLoadLabels() { manageSubscription( RxHelper.getObserver(RestProvider.getRepoService().getLabels(login, repoId)) .doOnSubscribe(this::onSubscribed) .doOnNext(response -> { if (response.getItems() != null && !response.getItems().isEmpty()) { sendToView(view -> view.onLabelsRetrieved(response.getItems())); } else { sendToView(view -> view.showMessage(R.string.error, R.string.no_labels)); } }) .onErrorReturn(throwable -> { sendToView(view -> view.showMessage(R.string.error, R.string.no_labels)); return null; }) .subscribe() ); } @Override public void onPutLabels(@NonNull ArrayList<LabelModel> labels) { makeRestCall(RestProvider.getIssueService().putLabels(login, repoId, issueNumber, Stream.of(labels).filter(value -> value != null && value.getName() != null) .map(LabelModel::getName).collect(Collectors.toList())), labelModels -> { sendToView(PullRequestPagerMvp.View::onUpdateTimeline); LabelListModel listModel = new LabelListModel(); listModel.addAll(labels); pullRequest.setLabels(listModel); manageSubscription(pullRequest.save(pullRequest).subscribe()); }); } @Override public void onPutMilestones(@NonNull MilestoneModel milestone) { pullRequest.setMilestone(milestone); IssueRequestModel issueRequestModel = IssueRequestModel.clone(pullRequest, false); makeRestCall(RestProvider.getPullRequestService().editIssue(login, repoId, issueNumber, issueRequestModel), pr -> { this.pullRequest = pr; pullRequest.setLogin(login); pullRequest.setRepoId(repoId); manageSubscription(pr.save(pullRequest).subscribe()); sendToView(PullRequestPagerMvp.View::onUpdateTimeline); }); } @Override public void onPutAssignees(@NonNull ArrayList<User> users, boolean isAssignees) { AssigneesRequestModel assigneesRequestModel = new AssigneesRequestModel(); ArrayList<String> assignees = Stream.of(users) .map(User::getLogin) .collect(Collectors.toCollection(ArrayList::new)); if (isAssignees) { assigneesRequestModel.setAssignees(assignees); makeRestCall(RestProvider.getPullRequestService().putAssignees(login, repoId, issueNumber, assigneesRequestModel), pullRequestResponse -> { this.pullRequest = pullRequestResponse; pullRequest.setLogin(login); pullRequest.setRepoId(repoId); UsersListModel assignee = new UsersListModel(); assignee.addAll(users); pullRequest.setAssignees(assignee); manageSubscription(pullRequest.save(pullRequest).subscribe()); sendToView(PullRequestPagerMvp.View::onUpdateTimeline); } ); } else { assigneesRequestModel.setReviewers(assignees); makeRestCall(RestProvider.getPullRequestService().putReviewers(login, repoId, issueNumber, assigneesRequestModel), pullRequestResponse -> sendToView(PullRequestPagerMvp.View::onUpdateTimeline) ); } } @Override public void onMerge(@NonNull String msg) { if (isMergeable() && (isCollaborator() || isRepoOwner())) {//double the checking if (getPullRequest() == null || getPullRequest().getHead() == null || getPullRequest().getHead().getSha() == null) return; MergeRequestModel mergeRequestModel = new MergeRequestModel(); mergeRequestModel.setSha(getPullRequest().getHead().getSha()); mergeRequestModel.setCommitMessage(msg); manageSubscription( RxHelper.getObserver(RestProvider.getPullRequestService().mergePullRequest(login, repoId, issueNumber, mergeRequestModel)) .doOnSubscribe(() -> sendToView(view -> view.showProgress(0))) .doOnNext(mergeResponseModel -> { if (mergeResponseModel.isMerged()) { sendToView(view -> { view.showMessage(R.string.success, R.string.success_merge); view.onUpdateTimeline(); }); } else { sendToView(view -> view.showErrorMessage(mergeResponseModel.getMessage())); } }) .onErrorReturn(throwable -> { sendToView(view -> view.showErrorMessage(throwable.getMessage())); return null; }) .subscribe() ); } } @Override public String getLogin() { return login; } @Override public String getRepoId() { return repoId; } @Override public boolean isCollaborator() { return isCollaborator; } @Override public void onUpdatePullRequest(@NonNull PullRequest pullRequestModel) { this.pullRequest = pullRequestModel; this.pullRequest.setLogin(login); this.pullRequest.setRepoId(repoId); manageSubscription(pullRequest.save(pullRequest).subscribe()); sendToView(PullRequestPagerMvp.View::onSetupIssue); } }