this fixes #13 where now one can add assignees and milestones to issue/pull.

This commit is contained in:
Kosh 2017-03-05 12:39:50 +08:00
parent 818b6d7fd6
commit 837b2652b5
27 changed files with 461 additions and 63 deletions

View File

@ -26,6 +26,7 @@ android {
buildConfigField "String", "GITHUB_SECRET", "\"${GITHUB_SECRET}\""
buildConfigField "String", "REDIRECT_URL", "\"${REDIRECT_URL}\""
buildConfigField "String", "REST_URL", '"https://api.github.com/"'
buildConfigField "int", "DB_VERSION", "2"
}
buildTypes {
release {

View File

@ -0,0 +1 @@
ALTER TABLE pull_request_model ADD COLUMN assignees TEXT

View File

@ -0,0 +1,16 @@
package com.fastaccess.data.dao;
import java.util.List;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Created by Kosh on 05 Mar 2017, 12:01 PM
*/
@Getter @Setter @NoArgsConstructor
public class AssigneesRequestModel {
private List<String> assignees;
}

View File

@ -10,7 +10,6 @@ import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.siimkinks.sqlitemagic.Delete;
import com.siimkinks.sqlitemagic.PullRequestModelTable;
import com.siimkinks.sqlitemagic.Select;
import com.siimkinks.sqlitemagic.annotation.Column;
import com.siimkinks.sqlitemagic.annotation.Id;
@ -25,6 +24,8 @@ import lombok.Setter;
import rx.Completable;
import rx.Observable;
import static com.siimkinks.sqlitemagic.PullRequestModelTable.PULL_REQUEST_MODEL;
/**
* Created by Kosh on 08 Dec 2016, 8:51 PM
*/
@ -68,14 +69,15 @@ public class PullRequestModel implements Parcelable {
@Column int reviewComments;
@Column String repoId;
@Column String login;
@Column UsersListModel assignees;
public Completable save() {
return persist().observe().toCompletable();
}
public static Completable save(@NonNull List<PullRequestModel> models, @NonNull String repoId, @NonNull String login) {
return Delete.from(PullRequestModelTable.PULL_REQUEST_MODEL)
.where(PullRequestModelTable.PULL_REQUEST_MODEL.REPO_ID.is(repoId))
return Delete.from(PULL_REQUEST_MODEL)
.where(PULL_REQUEST_MODEL.REPO_ID.is(repoId))
.observe()
.toCompletable()
.andThen(Observable.from(models)
@ -88,19 +90,19 @@ public class PullRequestModel implements Parcelable {
}
public static Observable<List<PullRequestModel>> getPullRequests(@NonNull String repoId, @NonNull String login, @NonNull IssueState issueState) {
return Select.from(PullRequestModelTable.PULL_REQUEST_MODEL)
.where(PullRequestModelTable.PULL_REQUEST_MODEL.REPO_ID.is(repoId)
.and(PullRequestModelTable.PULL_REQUEST_MODEL.LOGIN.is(login))
.and(PullRequestModelTable.PULL_REQUEST_MODEL.STATE.is(issueState)))
.orderBy(PullRequestModelTable.PULL_REQUEST_MODEL.UPDATED_AT.desc())
return Select.from(PULL_REQUEST_MODEL)
.where(PULL_REQUEST_MODEL.REPO_ID.is(repoId)
.and(PULL_REQUEST_MODEL.LOGIN.is(login))
.and(PULL_REQUEST_MODEL.STATE.is(issueState)))
.orderBy(PULL_REQUEST_MODEL.UPDATED_AT.desc())
.queryDeep()
.observe()
.runQuery();
}
public static Observable<PullRequestModel> getPullRequest(long id) {
return Select.from(PullRequestModelTable.PULL_REQUEST_MODEL)
.where(PullRequestModelTable.PULL_REQUEST_MODEL.ID.is(id))
return Select.from(PULL_REQUEST_MODEL)
.where(PULL_REQUEST_MODEL.ID.is(id))
.queryDeep()
.takeFirst()
.observe()
@ -108,10 +110,10 @@ public class PullRequestModel implements Parcelable {
}
public static Observable<PullRequestModel> getPullRequest(int number, @NonNull String repoId, @NonNull String login) {
return Select.from(PullRequestModelTable.PULL_REQUEST_MODEL)
.where(PullRequestModelTable.PULL_REQUEST_MODEL.NUMBER.is(number)
.and(PullRequestModelTable.PULL_REQUEST_MODEL.LOGIN.is(login))
.and(PullRequestModelTable.PULL_REQUEST_MODEL.REPO_ID.is(repoId)))
return Select.from(PULL_REQUEST_MODEL)
.where(PULL_REQUEST_MODEL.NUMBER.is(number)
.and(PULL_REQUEST_MODEL.LOGIN.is(login))
.and(PULL_REQUEST_MODEL.REPO_ID.is(repoId)))
.queryDeep()
.takeFirst()
.observe()
@ -177,6 +179,7 @@ public class PullRequestModel implements Parcelable {
dest.writeInt(this.reviewComments);
dest.writeString(this.repoId);
dest.writeString(this.login);
dest.writeList(this.assignees);
}
protected PullRequestModel(Parcel in) {
@ -223,6 +226,8 @@ public class PullRequestModel implements Parcelable {
this.reviewComments = in.readInt();
this.repoId = in.readString();
this.login = in.readString();
this.assignees = new UsersListModel();
in.readList(this.assignees, this.assignees.getClass().getClassLoader());
}
public static final Creator<PullRequestModel> CREATOR = new Creator<PullRequestModel>() {

View File

@ -3,6 +3,7 @@ package com.fastaccess.data.service;
import android.support.annotation.NonNull;
import com.fastaccess.data.dao.AssigneesRequestModel;
import com.fastaccess.data.dao.CommentRequestModel;
import com.fastaccess.data.dao.CommentsModel;
import com.fastaccess.data.dao.CreateIssueModel;
@ -87,4 +88,8 @@ public interface IssueService {
@POST("repos/{owner}/{repo}/issues/{number}/labels")
Observable<Pageable<LabelModel>> putLabels(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number, @Body @NonNull List<String> labels);
@POST("repos/{owner}/{repo}/issues/{number}/assignees")
Observable<IssueModel> putAssignees(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number, @Body AssigneesRequestModel body);
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.data.service;
import com.fastaccess.data.dao.AssigneesRequestModel;
import com.fastaccess.data.dao.CommitModel;
import com.fastaccess.data.dao.IssueRequestModel;
import com.fastaccess.data.dao.MergeRequestModel;
@ -12,6 +13,7 @@ import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
import retrofit2.http.Query;
@ -53,8 +55,13 @@ public interface PullRequestService {
Observable<PullRequestModel> editPullRequest(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number,
@Body IssueRequestModel issue);
@PATCH("repos/{owner}/{repo}/issues/{number}")
Observable<PullRequestModel> editIssue(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number,
@Body IssueRequestModel issue);
@POST("repos/{owner}/{repo}/issues/{number}/assignees")
Observable<PullRequestModel> putAssignees(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number, @Body AssigneesRequestModel body);
}

View File

@ -0,0 +1,39 @@
package com.fastaccess.ui;
import android.support.annotation.NonNull;
import android.view.ViewGroup;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.ui.adapter.viewholder.AssigneesViewHolder;
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import java.util.List;
/**
* Created by Kosh on 11 Nov 2016, 2:07 PM
*/
public class AssigneesAdapter extends BaseRecyclerAdapter<UserModel, AssigneesViewHolder, BaseViewHolder.OnItemClickListener<UserModel>> {
public interface OnSelectAssignee {
boolean isAssigneeSelected(int position);
void onToggleSelection(int position, boolean select);
}
private OnSelectAssignee onSelectAssignee;
public AssigneesAdapter(@NonNull List<UserModel> data, OnSelectAssignee onSelectAssignee) {
super(data);
this.onSelectAssignee = onSelectAssignee;
}
@Override protected AssigneesViewHolder viewHolder(ViewGroup parent, int viewType) {
return AssigneesViewHolder.newInstance(parent, onSelectAssignee);
}
@Override protected void onBindView(AssigneesViewHolder holder, int position) {
holder.bind(getItem(position));
}
}

View File

@ -0,0 +1,50 @@
package com.fastaccess.ui.adapter.viewholder;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import com.fastaccess.R;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.ui.AssigneesAdapter;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import butterknife.BindColor;
import butterknife.BindView;
/**
* Created by Kosh on 11 Nov 2016, 2:08 PM
*/
public class AssigneesViewHolder extends BaseViewHolder<UserModel> {
@BindView(R.id.avatarLayout) AvatarLayout avatar;
@BindView(R.id.title) FontTextView title;
@BindView(R.id.date) FontTextView date;
@BindColor(R.color.windowBackground) int windowBackground;
@BindColor(R.color.light_gray) int lightGray;
private AssigneesAdapter.OnSelectAssignee onSelectAssignee;
@Override public void onClick(View v) {
int position = getAdapterPosition();
onSelectAssignee.onToggleSelection(position, !onSelectAssignee.isAssigneeSelected(position));
}
private AssigneesViewHolder(@NonNull View itemView, @NonNull AssigneesAdapter.OnSelectAssignee onSelectAssignee) {
super(itemView);
this.onSelectAssignee = onSelectAssignee;
}
public static AssigneesViewHolder newInstance(@NonNull ViewGroup viewGroup, @NonNull AssigneesAdapter.OnSelectAssignee onSelectAssignee) {
return new AssigneesViewHolder(getView(viewGroup, R.layout.feeds_row_item), onSelectAssignee);
}
@Override public void bind(@NonNull UserModel user) {
avatar.setUrl(user.getAvatarUrl(), user.getLogin());
title.setText(user.getLogin());
date.setVisibility(View.GONE);
itemView.setBackgroundColor(onSelectAssignee.isAssigneeSelected(getAdapterPosition()) ? lightGray : windowBackground);
}
}

View File

@ -57,9 +57,11 @@ public class GistView extends BaseActivity<GistMvp.View, GistPresenter>
}
@OnClick(R.id.fab) void onAddComment() {
GistCommentsView view = (GistCommentsView) pager.getAdapter().instantiateItem(pager, 1);
if (view != null) {
view.onStartNewComment();
if (pager != null && pager.getAdapter() != null) {
GistCommentsView view = (GistCommentsView) pager.getAdapter().instantiateItem(pager, 1);
if (view != null) {
view.onStartNewComment();
}
}
}

View File

@ -66,7 +66,7 @@ public class LoginView extends BaseActivity<LoginMvp.View, LoginPresenter> imple
if (progress == 100) {
refresh.setRefreshing(false);
} else if (progress < 100) {
refresh.setRefreshing(true);
}
}
});

View File

@ -0,0 +1,24 @@
package com.fastaccess.ui.modules.repos.extras.assignees;
import android.support.annotation.NonNull;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.ui.AssigneesAdapter;
import com.fastaccess.ui.base.mvp.BaseMvp;
import java.util.ArrayList;
/**
* Created by Kosh on 22 Feb 2017, 7:22 PM
*/
public interface AssigneesMvp {
interface SelectedAssigneesListener {
void onSelectedAssignees(@NonNull ArrayList<UserModel> users);
}
interface View extends BaseMvp.FAView, AssigneesAdapter.OnSelectAssignee {}
interface Presenter {}
}

View File

@ -0,0 +1,9 @@
package com.fastaccess.ui.modules.repos.extras.assignees;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
/**
* Created by Kosh on 05 Mar 2017, 11:52 AM
*/
class AssigneesPresenter extends BasePresenter<AssigneesMvp.View> implements AssigneesMvp.Presenter {}

View File

@ -0,0 +1,119 @@
package com.fastaccess.ui.modules.repos.extras.assignees;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.fastaccess.R;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.Bundler;
import com.fastaccess.ui.AssigneesAdapter;
import com.fastaccess.ui.base.BaseDialogFragment;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import butterknife.BindView;
import butterknife.OnClick;
import icepick.State;
/**
* Created by Kosh on 22 Feb 2017, 7:23 PM
*/
public class AssigneesView extends BaseDialogFragment<AssigneesMvp.View, AssigneesPresenter> implements AssigneesMvp.View {
@BindView(R.id.title) FontTextView title;
@BindView(R.id.recycler) DynamicRecyclerView recycler;
@State HashMap<Integer, UserModel> selectionMap;
private AssigneesAdapter adapter;
private AssigneesMvp.SelectedAssigneesListener callback;
@Override public void onAttach(Context context) {
super.onAttach(context);
if (getParentFragment() instanceof AssigneesMvp.SelectedAssigneesListener) {
callback = (AssigneesMvp.SelectedAssigneesListener) getParentFragment();
} else if (context instanceof AssigneesMvp.SelectedAssigneesListener) {
callback = (AssigneesMvp.SelectedAssigneesListener) context;
} else {
throw new IllegalArgumentException("Parent Fragment or Activity must implement AssigneesMvp.SelectedAssigneesListener");
}
}
@Override public void onDetach() {
super.onDetach();
callback = null;
}
public static AssigneesView newInstance(@NonNull List<UserModel> models) {
AssigneesView fragment = new AssigneesView();
fragment.setArguments(Bundler.start().putParcelableArrayList(BundleConstant.ITEM, (ArrayList<? extends Parcelable>) models).end());
return fragment;
}
@Override protected int fragmentLayout() {
return R.layout.simple_footer_list_dialog;
}
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
title.setText(R.string.assignees);
List<UserModel> list = getArguments().getParcelableArrayList(BundleConstant.ITEM);
if (list != null) {
adapter = new AssigneesAdapter(list, this);
recycler.setAdapter(adapter);
}
}
@NonNull @Override public AssigneesPresenter providePresenter() {
return new AssigneesPresenter();
}
@Override public boolean isAssigneeSelected(int position) {
return getSelectionMap().get(position) != null;
}
@Override public void onToggleSelection(int position, boolean select) {
if (select) {
getSelectionMap().put(position, adapter.getItem(position));
} else {
getSelectionMap().remove(position);
}
adapter.notifyDataSetChanged();
}
@OnClick({R.id.cancel, R.id.ok}) public void onClick(View view) {
switch (view.getId()) {
case R.id.cancel:
dismiss();
break;
case R.id.ok:
ArrayList<UserModel> labels = Stream.of(selectionMap)
.filter(value -> value.getValue() != null)
.map(Map.Entry::getValue)
.collect(Collectors.toCollection(ArrayList::new));
if (labels != null && !labels.isEmpty()) {
callback.onSelectedAssignees(labels);
}
dismiss();
break;
}
}
public HashMap<Integer, UserModel> getSelectionMap() {
if (selectionMap == null) {
selectionMap = new LinkedHashMap<>();
}
return selectionMap;
}
}

View File

@ -1,4 +1,4 @@
package com.fastaccess.ui.modules.repos.labels;
package com.fastaccess.ui.modules.repos.extras.labels;
import android.support.annotation.NonNull;

View File

@ -0,0 +1,9 @@
package com.fastaccess.ui.modules.repos.extras.labels;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
/**
* Created by Kosh on 22 Feb 2017, 7:23 PM
*/
class LabelsPresenter extends BasePresenter<LabelsMvp.View> implements LabelsMvp.Presenter {}

View File

@ -1,4 +1,4 @@
package com.fastaccess.ui.modules.repos.labels;
package com.fastaccess.ui.modules.repos.extras.labels;
import android.content.Context;
import android.os.Bundle;
@ -89,7 +89,7 @@ public class LabelsView extends BaseDialogFragment<LabelsMvp.View, LabelsPresent
} else {
getSelectionMap().remove(position);
}
adapter.notifyItemChanged(position);
adapter.notifyDataSetChanged();
}
@OnClick({R.id.cancel, R.id.ok}) public void onClick(View view) {

View File

@ -88,6 +88,8 @@ public class MilestoneView extends BaseFragment<MilestoneMvp.View, MilestonePres
toolbar.setTitle(R.string.milestone);
toolbar.setOnMenuItemClickListener(item -> onAddMilestone());
toolbar.inflateMenu(R.menu.add_menu);
toolbar.setNavigationIcon(R.drawable.ic_back);
toolbar.setNavigationOnClickListener(v -> getActivity().finish());
adapter = new MilestonesAdapter(getPresenter().getMilestones());
adapter.setListener(getPresenter());
recycler.setEmptyView(stateLayout, refresh);

View File

@ -8,8 +8,10 @@ import android.support.annotation.Nullable;
import com.fastaccess.data.dao.IssueModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.repos.labels.LabelsMvp;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesMvp;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsMvp;
import java.util.ArrayList;
import java.util.List;
@ -20,7 +22,8 @@ import java.util.List;
interface IssuePagerMvp {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
AssigneesMvp.SelectedAssigneesListener {
void onSetupIssue();
void showSuccessIssueActionMsg(boolean isClose);
@ -32,6 +35,8 @@ interface IssuePagerMvp {
void onUpdateTimeline();
void onUpdateMenu();
void onShowAssignees(@NonNull List<UserModel> items);
}
interface Presenter extends BaseMvp.FAPresenter {
@ -58,10 +63,14 @@ interface IssuePagerMvp {
void onLoadLabels();
void onLoadAssignees();
void onPutMilestones(@NonNull MilestoneModel milestone);
void onPutLabels(@NonNull ArrayList<LabelModel> labels);
void onPutAssignees(@NonNull ArrayList<UserModel> users);
String getLogin();
String getRepoId();

View File

@ -9,6 +9,7 @@ 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.IssueModel;
import com.fastaccess.data.dao.IssueRequestModel;
import com.fastaccess.data.dao.LabelListModel;
@ -17,6 +18,7 @@ import com.fastaccess.data.dao.LoginModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.data.dao.UsersListModel;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.data.service.IssueService;
import com.fastaccess.helper.BundleConstant;
@ -192,6 +194,17 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
);
}
@Override public void onLoadAssignees() {
makeRestCall(RestProvider.getRepoService().getAssignees(login, repoId),
response -> {
if (response != null && response.getItems() != null && !response.getItems().isEmpty()) {
sendToView(view -> view.onShowAssignees(response.getItems()));
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.no_assignees));
}
});
}
@Override public void onPutMilestones(@NonNull MilestoneModel milestone) {
issueModel.setMilestone(milestone);
IssueRequestModel issueRequestModel = IssueRequestModel.clone(issueModel, false);
@ -219,6 +232,25 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
});
}
@Override public void onPutAssignees(@NonNull ArrayList<UserModel> users) {
AssigneesRequestModel assigneesRequestModel = new AssigneesRequestModel();
ArrayList<String> assignees = new ArrayList<>();
Stream.of(users).forEach(userModel -> assignees.add(userModel.getLogin()));
assigneesRequestModel.setAssignees(assignees);
makeRestCall(RestProvider.getIssueService().putAssignees(login, repoId, issueNumber, assigneesRequestModel),
issue -> {
this.issueModel = issue;
issueModel.setLogin(login);
issueModel.setRepoId(repoId);
UsersListModel assignee = new UsersListModel();
assignee.addAll(users);
issueModel.setAssignees(assignee);
manageSubscription(issueModel.save().subscribe());
sendToView(IssuePagerMvp.View::onUpdateTimeline);
}
);
}
@Override public String getLogin() {
return login;
}

View File

@ -27,11 +27,12 @@ import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesView;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsView;
import com.fastaccess.ui.modules.repos.extras.milestone.create.MilestoneActivityView;
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueView;
import com.fastaccess.ui.modules.repos.issues.issue.details.comments.IssueCommentsView;
import com.fastaccess.ui.modules.repos.issues.issue.details.events.IssueDetailsView;
import com.fastaccess.ui.modules.repos.labels.LabelsView;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.ForegroundImageView;
@ -170,6 +171,10 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
return true;
} else if (item.getItemId() == R.id.milestone) {
MilestoneActivityView.startActivity(this, getPresenter().getLogin(), getPresenter().getRepoId());
return true;
} else if (item.getItemId() == R.id.assignees) {
getPresenter().onLoadAssignees();
return true;
}
return super.onOptionsItemSelected(item);
}
@ -186,7 +191,7 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
boolean isLocked = getPresenter().isLocked();
boolean isCollaborator = getPresenter().isCollaborator();
boolean isRepoOwner = getPresenter().isRepoOwner();
editMenu.setVisible(isOwner || isCollaborator);
editMenu.setVisible(isOwner || isCollaborator || isRepoOwner);
milestone.setVisible(isCollaborator || isRepoOwner);
labels.setVisible(isCollaborator || isRepoOwner);
assignees.setVisible(isCollaborator || isRepoOwner);
@ -195,11 +200,10 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
menu.findItem(R.id.lockIssue).setVisible(isOwner || isCollaborator);
menu.findItem(R.id.labels).setVisible(getPresenter().isRepoOwner() || isCollaborator);
if (isOwner) {
//noinspection ConstantConditions ( getIssue at this stage is not null but AS doesn't know. )
if (getPresenter().getIssue() == null) return super.onPrepareOptionsMenu(menu);
closeIssue.setTitle(getPresenter().getIssue().getState() == IssueState.closed ? getString(R.string.re_open) : getString(R.string.close));
lockIssue.setTitle(isLocked ? getString(R.string.unlock_issue) : getString(R.string.lock_issue));
}
return super.onPrepareOptionsMenu(menu);
}
@ -279,6 +283,12 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
supportInvalidateOptionsMenu();
}
@Override public void onShowAssignees(@NonNull List<UserModel> items) {
hideProgress();
AssigneesView.newInstance(items)
.show(getSupportFragmentManager(), "AssigneesView");
}
@Override public void onMessageDialogActionClicked(boolean isOk, @Nullable Bundle bundle) {
super.onMessageDialogActionClicked(isOk, bundle);
if (isOk) {
@ -291,6 +301,10 @@ public class IssuePagerView extends BaseActivity<IssuePagerMvp.View, IssuePagerP
getPresenter().onPutLabels(labels);
}
@Override public void onSelectedAssignees(@NonNull ArrayList<UserModel> users) {
getPresenter().onPutAssignees(users);
}
private void hideShowFab() {
if (getPresenter().isLocked() && !getPresenter().isOwner()) {
fab.hide();

View File

@ -1,9 +0,0 @@
package com.fastaccess.ui.modules.repos.labels;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
/**
* Created by Kosh on 22 Feb 2017, 7:23 PM
*/
public class LabelsPresenter extends BasePresenter<LabelsMvp.View> implements LabelsMvp.Presenter {}

View File

@ -9,8 +9,10 @@ import android.support.annotation.Nullable;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullRequestModel;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.repos.labels.LabelsMvp;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesMvp;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsMvp;
import com.fastaccess.ui.widgets.SpannableBuilder;
import java.util.ArrayList;
@ -22,8 +24,8 @@ import java.util.List;
interface PullRequestPagerMvp {
interface
View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
AssigneesMvp.SelectedAssigneesListener {
void onSetupIssue();
@ -36,6 +38,8 @@ interface PullRequestPagerMvp {
void showErrorIssueActionMsg(boolean isClose);
void onUpdateTimeline();
void onShowAssignees(@NonNull List<UserModel> items);
}
interface Presenter extends BaseMvp.FAPresenter {
@ -66,10 +70,14 @@ interface PullRequestPagerMvp {
void onLoadLabels();
void onLoadAssignees();
void onPutLabels(@NonNull ArrayList<LabelModel> labels);
void onPutMilestones(@NonNull MilestoneModel milestone);
void onPutAssignees(@NonNull ArrayList<UserModel> users);
String getLogin();
String getRepoId();

View File

@ -10,6 +10,7 @@ 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;
@ -19,6 +20,7 @@ import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullRequestModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.data.dao.UsersListModel;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.data.service.IssueService;
import com.fastaccess.helper.BundleConstant;
@ -191,6 +193,17 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
);
}
@Override public void onLoadAssignees() {
makeRestCall(RestProvider.getRepoService().getAssignees(login, repoId),
response -> {
if (response != null && response.getItems() != null && !response.getItems().isEmpty()) {
sendToView(view -> view.onShowAssignees(response.getItems()));
} else {
sendToView(view -> view.showMessage(R.string.error, R.string.no_assignees));
}
});
}
@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)
@ -218,6 +231,25 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
}
@Override public void onPutAssignees(@NonNull ArrayList<UserModel> users) {
AssigneesRequestModel assigneesRequestModel = new AssigneesRequestModel();
ArrayList<String> assignees = new ArrayList<>();
Stream.of(users).forEach(userModel -> assignees.add(userModel.getLogin()));
assigneesRequestModel.setAssignees(assignees);
makeRestCall(RestProvider.getPullRequestSerice().putAssignees(login, repoId, issueNumber, assigneesRequestModel),
issue -> {
this.pullRequest = issue;
pullRequest.setLogin(login);
pullRequest.setRepoId(repoId);
UsersListModel assignee = new UsersListModel();
assignee.addAll(users);
pullRequest.setAssignees(assignee);
manageSubscription(pullRequest.save().subscribe());
sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
}
);
}
@Override public void onMerge() {
if (isMergeable() && (isCollaborator() || isRepoOwner())) {//double the checking
MergeRequestModel mergeRequestModel = new MergeRequestModel();

View File

@ -26,10 +26,11 @@ import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesView;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsView;
import com.fastaccess.ui.modules.repos.extras.milestone.create.MilestoneActivityView;
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueView;
import com.fastaccess.ui.modules.repos.issues.issue.details.comments.IssueCommentsView;
import com.fastaccess.ui.modules.repos.labels.LabelsView;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.events.PullRequestDetailsView;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
@ -165,6 +166,10 @@ public class PullRequestPagerView extends BaseActivity<PullRequestPagerMvp.View,
return true;
} else if (item.getItemId() == R.id.milestone) {
MilestoneActivityView.startActivity(this, getPresenter().getLogin(), getPresenter().getRepoId());
return true;
} else if (item.getItemId() == R.id.assignees) {
getPresenter().onLoadAssignees();
return true;
}
return super.onOptionsItemSelected(item);
}
@ -181,7 +186,7 @@ public class PullRequestPagerView extends BaseActivity<PullRequestPagerMvp.View,
boolean isLocked = getPresenter().isLocked();
boolean isCollaborator = getPresenter().isCollaborator();
boolean isRepoOwner = getPresenter().isRepoOwner();
editMenu.setVisible(isOwner || isCollaborator);
editMenu.setVisible(isOwner || isCollaborator || isRepoOwner);
milestone.setVisible(isCollaborator || isRepoOwner);
labels.setVisible(isCollaborator || isRepoOwner);
assignees.setVisible(isCollaborator || isRepoOwner);
@ -189,8 +194,8 @@ public class PullRequestPagerView extends BaseActivity<PullRequestPagerMvp.View,
if (getPresenter().getPullRequest() != null) {
closeIssue.setVisible(isRepoOwner || (isOwner || isCollaborator) && getPresenter().getPullRequest().getState() == IssueState.open);
lockIssue.setVisible(isRepoOwner || (isOwner || isCollaborator) && getPresenter().getPullRequest().getState() == IssueState.open);
closeIssue.setTitle(getPresenter().getPullRequest().getState() == IssueState.closed
? getString(R.string.re_open) : getString(R.string.close));
closeIssue.setTitle(getPresenter().getPullRequest().getState() == IssueState.closed ? getString(R.string.re_open) : getString(R.string
.close));
lockIssue.setTitle(isLocked ? getString(R.string.unlock_issue) : getString(R.string.lock_issue));
} else {
closeIssue.setVisible(false);
@ -254,6 +259,10 @@ public class PullRequestPagerView extends BaseActivity<PullRequestPagerMvp.View,
getPresenter().onPutLabels(labels);
}
@Override public void onSelectedAssignees(@NonNull ArrayList<UserModel> users) {
getPresenter().onPutAssignees(users);
}
@Override public void showSuccessIssueActionMsg(boolean isClose) {
hideProgress();
if (isClose) {
@ -280,6 +289,12 @@ public class PullRequestPagerView extends BaseActivity<PullRequestPagerMvp.View,
}
}
@Override public void onShowAssignees(@NonNull List<UserModel> items) {
hideProgress();
AssigneesView.newInstance(items)
.show(getSupportFragmentManager(), "AssigneesView");
}
private void hideShowFab() {
if (getPresenter().isLocked() && !getPresenter().isOwner()) {
fab.hide();

View File

@ -10,10 +10,24 @@
android:title="@string/action"
app:showAsAction="always">
<menu>
<item
android:id="@+id/edit"
android:icon="@drawable/ic_edit"
android:title="@string/edit"/>
<item
android:id="@+id/lockIssue"
android:icon="@drawable/ic_lock"
android:title="@string/lock_issue"
app:showAsAction="never"/>
<item
android:id="@+id/closeIssue"
android:icon="@drawable/ic_issues"
android:title="@string/close_issue"
app:showAsAction="never"/>
<item
android:id="@+id/labels"
android:icon="@drawable/ic_label"
@ -36,15 +50,5 @@
android:title="@string/share"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/lockIssue"
android:title="@string/lock_issue"
app:showAsAction="never"/>
<item
android:id="@+id/closeIssue"
android:title="@string/close_issue"
app:showAsAction="never"/>
</menu>

View File

@ -10,10 +10,23 @@
android:title="@string/action"
app:showAsAction="always">
<menu>
<item
android:id="@+id/edit"
android:icon="@drawable/ic_edit"
android:title="@string/edit"/>
<item
android:id="@+id/lockIssue"
android:icon="@drawable/ic_lock"
android:title="@string/lock_issue"
app:showAsAction="never"/>
<item
android:id="@+id/closeIssue"
android:icon="@drawable/ic_issues"
android:title="@string/close_issue"
app:showAsAction="never"/>
<item
android:id="@+id/labels"
android:icon="@drawable/ic_label"
@ -42,14 +55,4 @@
android:title="@string/share"
app:showAsAction="never"/>
<item
android:id="@+id/lockIssue"
android:title="@string/lock_issue"
app:showAsAction="never"/>
<item
android:id="@+id/closeIssue"
android:title="@string/close_issue"
app:showAsAction="never"/>
</menu>

View File

@ -226,4 +226,5 @@
<string name="create_milestone">Create Milestone</string>
<string name="error_creating_milestone">Error creating milestone</string>
<string name="due_on">Due On</string>
<string name="no_assignees">No Assignees</string>
</resources>