diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index da640a82..d7a57f36 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -85,6 +85,7 @@
+
diff --git a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java
new file mode 100644
index 00000000..e066deb5
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java
@@ -0,0 +1,431 @@
+package org.mian.gitnex.activities;
+
+import android.app.DatePickerDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import androidx.annotation.NonNull;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.LabelsListAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.ActivityCreatePrBinding;
+import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.StaticGlobalVariables;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import org.mian.gitnex.models.Branches;
+import org.mian.gitnex.models.CreatePullRequest;
+import org.mian.gitnex.models.Labels;
+import org.mian.gitnex.models.Milestones;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Callback;
+
+/**
+ * Author M M Arif
+ */
+
+public class CreatePullRequestActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener {
+
+ private View.OnClickListener onClickListener;
+ private Context ctx = this;
+ private Context appCtx;
+ private TinyDB tinyDb;
+ private ActivityCreatePrBinding viewBinding;
+ private CustomLabelsSelectionDialogBinding labelsBinding;
+ private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances;
+ private Dialog dialogLabels;
+ private String labelsSetter;
+ private ArrayList labelsIds = new ArrayList<>();
+ private ArrayList assignees = new ArrayList<>();
+ private int milestoneId;
+
+ private String instanceUrl;
+ private String loginUid;
+ private String instanceToken;
+ private String repoOwner;
+ private String repoName;
+
+ private LabelsListAdapter labelsAdapter;
+
+ List milestonesList = new ArrayList<>();
+ List branchesList = new ArrayList<>();
+ List labelsList = new ArrayList<>();
+
+ public CreatePullRequestActivity() {
+ }
+
+ @Override
+ protected int getLayoutResourceId(){
+ return R.layout.activity_create_pr;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+ appCtx = getApplicationContext();
+ tinyDb = new TinyDB(appCtx);
+
+ viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater());
+ View view = viewBinding.getRoot();
+ setContentView(view);
+
+ instanceUrl = tinyDb.getString("instanceUrl");
+ loginUid = tinyDb.getString("loginUid");
+ String repoFullName = tinyDb.getString("repoFullName");
+ String[] parts = repoFullName.split("/");
+ repoOwner = parts[0];
+ repoName = parts[1];
+ instanceToken = "token " + tinyDb.getString(loginUid + "-token");
+
+ // require gitea 1.12 or higher
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
+ }
+
+ labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this);
+
+ ImageView closeActivity = findViewById(R.id.close);
+
+ initCloseListener();
+ closeActivity.setOnClickListener(onClickListener);
+
+ viewBinding.prDueDate.setOnClickListener(dueDate ->
+ setDueDate()
+ );
+
+ disableProcessButton();
+
+ getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit);
+ getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
+
+ viewBinding.prLabels.setOnClickListener(prLabels ->
+ showLabels()
+ );
+
+ viewBinding.createPr.setOnClickListener(createPr ->
+ processPullRequest()
+ );
+ }
+
+ private void processPullRequest() {
+
+ String prTitle = String.valueOf(viewBinding.prTitle.getText());
+ String prDescription = String.valueOf(viewBinding.prBody.getText());
+ String mergeInto = viewBinding.mergeIntoBranchSpinner.getText().toString();
+ String pullFrom = viewBinding.pullFromBranchSpinner.getText().toString();
+ String dueDate = String.valueOf(viewBinding.prDueDate.getText());
+
+ assignees.add("");
+
+ if (labelsIds.size() == 0) {
+ labelsIds.add(0);
+ }
+
+ if (dueDate.matches("")) {
+ dueDate = null;
+ }
+ else {
+ dueDate = AppUtil.customDateCombine(AppUtil.customDateFormat(dueDate));
+ }
+
+ if(prTitle.matches("")) {
+
+ Toasty.error(ctx, getString(R.string.titleError));
+ }
+ else if(mergeInto.matches("")) {
+
+ Toasty.error(ctx, getString(R.string.mergeIntoError));
+ }
+ else if(pullFrom.matches("")) {
+
+ Toasty.error(ctx, getString(R.string.pullFromError));
+ }
+ else if(pullFrom.equals(mergeInto)) {
+
+ Toasty.error(ctx, getString(R.string.sameBranchesError));
+ }
+ else {
+ createPullRequest(prTitle, prDescription, mergeInto, pullFrom, milestoneId, dueDate, assignees);
+ }
+ //Log.e("processPullRequest", String.valueOf(milestoneId));
+ }
+
+ private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, ArrayList assignees) {
+
+ CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds);
+
+ Call transferCall = RetrofitClient
+ .getInstance(instanceUrl, ctx)
+ .getApiInterface()
+ .createPullRequest(instanceToken, repoOwner, repoName, createPullRequest);
+
+ transferCall.enqueue(new Callback() {
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ disableProcessButton();
+
+ if (response.code() == 201) {
+
+ Toasty.success(ctx, getString(R.string.prCreateSuccess));
+ finish();
+ }
+ else if (response.code() == 409 && response.message().equals("Conflict")) {
+
+ enableProcessButton();
+ Toasty.error(ctx, getString(R.string.prAlreadyExists));
+ }
+ else if (response.code() == 404) {
+
+ enableProcessButton();
+ Toasty.error(ctx, getString(R.string.apiNotFound));
+ }
+ else {
+
+ enableProcessButton();
+ Toasty.error(ctx, getString(R.string.genericError));
+ }
+
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+
+ enableProcessButton();
+ Toasty.error(ctx, getString(R.string.genericServerResponseError));
+ }
+ });
+ }
+
+ @Override
+ public void labelsStringData(ArrayList data) {
+
+ labelsSetter = String.valueOf(data);
+ viewBinding.prLabels.setText(labelsSetter.replace("]", "").replace("[", ""));
+ }
+
+ @Override
+ public void labelsIdsData(ArrayList data) {
+
+ labelsIds = data;
+ }
+
+ private void showLabels() {
+
+ dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert);
+
+ if (dialogLabels.getWindow() != null) {
+ dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ }
+
+ labelsBinding = CustomLabelsSelectionDialogBinding.inflate(LayoutInflater.from(ctx));
+
+ View view = labelsBinding.getRoot();
+ dialogLabels.setContentView(view);
+
+ labelsBinding.cancel.setOnClickListener(editProperties ->
+ dialogLabels.dismiss()
+ );
+
+ Call> call = RetrofitClient
+ .getInstance(instanceUrl, ctx)
+ .getApiInterface()
+ .getlabels(instanceToken, repoOwner, repoName);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) {
+
+ labelsList.clear();
+ List labelsList_ = response.body();
+
+ labelsBinding.progressBar.setVisibility(View.GONE);
+ labelsBinding.dialogFrame.setVisibility(View.VISIBLE);
+
+ if (response.code() == 200) {
+
+ assert labelsList_ != null;
+ if(labelsList_.size() > 0) {
+ for (int i = 0; i < labelsList_.size(); i++) {
+
+ labelsList.add(new Labels(labelsList_.get(i).getId(), labelsList_.get(i).getName()));
+
+ }
+ }
+ else {
+
+ dialogLabels.dismiss();
+ Toasty.warning(ctx, getString(R.string.noLabelsFound));
+ }
+
+ labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter);
+
+ }
+ else {
+
+ Toasty.error(ctx, getString(R.string.genericError));
+ }
+
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+
+ Toasty.error(ctx, getString(R.string.genericServerResponseError));
+ }
+ });
+
+ dialogLabels.show();
+
+ }
+
+ private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
+
+ Call> call = RetrofitClient
+ .getInstance(instanceUrl, ctx)
+ .getApiInterface()
+ .getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) {
+
+ if(response.isSuccessful()) {
+ if(response.code() == 200) {
+
+ List branchesList_ = response.body();
+
+ assert branchesList_ != null;
+ if(branchesList_.size() > 0) {
+ for (int i = 0; i < branchesList_.size(); i++) {
+
+ Branches data = new Branches(
+ branchesList_.get(i).getName()
+ );
+ branchesList.add(data);
+
+ }
+ }
+
+ ArrayAdapter adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
+ R.layout.list_spinner_items, branchesList);
+
+ viewBinding.mergeIntoBranchSpinner.setAdapter(adapter);
+ viewBinding.pullFromBranchSpinner.setAdapter(adapter);
+ enableProcessButton();
+
+ }
+ }
+
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+
+ Toasty.error(ctx, getString(R.string.genericServerResponseError));
+ }
+ });
+
+ }
+
+ private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) {
+
+ String msState = "open";
+ Call> call = RetrofitClient
+ .getInstance(instanceUrl, ctx)
+ .getApiInterface()
+ .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) {
+
+ if(response.code() == 200) {
+
+ List milestonesList_ = response.body();
+
+ milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone)));
+ assert milestonesList_ != null;
+ if(milestonesList_.size() > 0) {
+ for (int i = 0; i < milestonesList_.size(); i++) {
+
+ //Don't translate "open" is a enum
+ if(milestonesList_.get(i).getState().equals("open")) {
+ Milestones data = new Milestones(
+ milestonesList_.get(i).getId(),
+ milestonesList_.get(i).getTitle()
+ );
+ milestonesList.add(data);
+ }
+
+ }
+ }
+
+ ArrayAdapter adapter = new ArrayAdapter<>(CreatePullRequestActivity.this,
+ R.layout.list_spinner_items, milestonesList);
+
+ viewBinding.milestonesSpinner.setAdapter(adapter);
+ enableProcessButton();
+
+ viewBinding.milestonesSpinner.setOnItemClickListener ((parent, view, position, id) ->
+
+ milestoneId = milestonesList.get(position).getId()
+ );
+
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+
+ Toasty.error(ctx, getString(R.string.genericServerResponseError));
+ }
+ });
+
+ }
+
+ private void setDueDate() {
+
+ final Calendar c = Calendar.getInstance();
+ int mYear = c.get(Calendar.YEAR);
+ final int mMonth = c.get(Calendar.MONTH);
+ final int mDay = c.get(Calendar.DAY_OF_MONTH);
+
+ DatePickerDialog datePickerDialog = new DatePickerDialog(this,
+ (view, year, monthOfYear, dayOfMonth) -> viewBinding.prDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay);
+ datePickerDialog.show();
+ }
+
+ private void initCloseListener() {
+
+ onClickListener = view -> finish();
+ }
+
+ private void disableProcessButton() {
+
+ viewBinding.createPr.setEnabled(false);
+ }
+
+ private void enableProcessButton() {
+
+ viewBinding.createPr.setEnabled(true);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java
index e3743446..80b00689 100644
--- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java
@@ -406,6 +406,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
startActivity(new Intent(RepoDetailActivity.this, RepositorySettingsActivity.class));
break;
+ case "newPullRequest":
+ startActivity(new Intent(RepoDetailActivity.this, CreatePullRequestActivity.class));
+ break;
+
}
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java
index d6dff0b5..e4c0ff96 100644
--- a/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java
@@ -394,6 +394,9 @@ public class RepositorySettingsActivity extends BaseActivity {
if (response.code() == 200) {
+ tinyDb.putBoolean("hasIssues", repoEnableIssues);
+ tinyDb.putBoolean("hasPullRequests", repoEnablePr);
+
dialogProp.dismiss();
Toasty.success(ctx, getString(R.string.repoPropertiesSaveSuccess));
diff --git a/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java
new file mode 100644
index 00000000..92b8ba54
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java
@@ -0,0 +1,95 @@
+package org.mian.gitnex.adapters;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import org.mian.gitnex.R;
+import org.mian.gitnex.models.Labels;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Author M M Arif
+ */
+
+public class LabelsListAdapter extends RecyclerView.Adapter {
+
+ private List labels;
+ private ArrayList labelsStrings = new ArrayList<>();
+ private ArrayList labelsIds = new ArrayList<>();
+
+ private LabelsListAdapterListener labelsListener;
+
+ public interface LabelsListAdapterListener {
+
+ void labelsStringData(ArrayList data);
+ void labelsIdsData(ArrayList data);
+ }
+
+ public LabelsListAdapter(List labelsMain, LabelsListAdapterListener labelsListener) {
+
+ this.labels = labelsMain;
+ this.labelsListener = labelsListener;
+ }
+
+ static class LabelsViewHolder extends RecyclerView.ViewHolder {
+
+ private CheckBox labelSelection;
+
+ private LabelsViewHolder(View itemView) {
+ super(itemView);
+
+ labelSelection = itemView.findViewById(R.id.labelSelection);
+
+ }
+ }
+
+ @NonNull
+ @Override
+ public LabelsListAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_labels_list, parent, false);
+ return new LabelsListAdapter.LabelsViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull LabelsListAdapter.LabelsViewHolder holder, int position) {
+
+ Labels currentItem = labels.get(position);
+
+ holder.labelSelection.setText(currentItem.getName());
+
+ for(int i = 0; i < labelsIds.size(); i++) {
+
+ if(labelsStrings.contains(currentItem.getName())) {
+
+ holder.labelSelection.setChecked(true);
+ }
+ }
+
+ holder.labelSelection.setOnCheckedChangeListener((buttonView, isChecked) -> {
+
+ if(isChecked) {
+
+ labelsStrings.add(currentItem.getName());
+ labelsIds.add(currentItem.getId());
+ }
+ else {
+
+ labelsStrings.remove(currentItem.getName());
+ labelsIds.remove(Integer.valueOf(currentItem.getId()));
+ }
+
+ labelsListener.labelsStringData(labelsStrings);
+ labelsListener.labelsIdsData(labelsIds);
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return labels.size();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java
index dd097632..f99ea3a1 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java
@@ -43,6 +43,7 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
TextView copyRepoUrl = v.findViewById(R.id.copyRepoUrl);
View repoSettingsDivider = v.findViewById(R.id.repoSettingsDivider);
TextView repoSettings = v.findViewById(R.id.repoSettings);
+ TextView createPullRequest = v.findViewById(R.id.createPullRequest);
createLabel.setOnClickListener(v112 -> {
@@ -64,6 +65,20 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment {
createIssue.setVisibility(View.GONE);
}
+ if(tinyDb.getBoolean("hasPullRequests")) {
+
+ createPullRequest.setVisibility(View.VISIBLE);
+ createPullRequest.setOnClickListener(vPr -> {
+
+ bmListener.onButtonClicked("newPullRequest");
+ dismiss();
+ });
+ }
+ else {
+
+ createPullRequest.setVisibility(View.GONE);
+ }
+
createMilestone.setOnClickListener(v13 -> {
bmListener.onButtonClicked("newMilestone");
diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
index 77a68ab9..4ab393d3 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
@@ -32,7 +32,6 @@ import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
@@ -112,7 +111,7 @@ public class IssuesFragment extends Fragment {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(adapter);
- ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListener(issueState -> {
+ ((RepoDetailActivity) requireActivity()).setFragmentRefreshListener(issueState -> {
if(issueState.equals("closed")) {
menu.getItem(1).setIcon(R.drawable.ic_filter_closed);
diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java
index bdf79e30..58e96a16 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java
@@ -351,6 +351,13 @@ public class RepoInfoFragment extends Fragment {
tinyDb.putBoolean("hasIssues", true);
}
+ if(repoInfo.isHas_pull_requests()) {
+ tinyDb.putBoolean("hasPullRequests", repoInfo.isHas_pull_requests());
+ }
+ else {
+ tinyDb.putBoolean("hasPullRequests", false);
+ }
+
tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url());
mProgressBar.setVisibility(View.GONE);
diff --git a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
index 6c7a78fb..460b2cea 100644
--- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
+++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
@@ -7,6 +7,7 @@ import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.Commits;
import org.mian.gitnex.models.CreateIssue;
import org.mian.gitnex.models.CreateLabel;
+import org.mian.gitnex.models.CreatePullRequest;
import org.mian.gitnex.models.DeleteFile;
import org.mian.gitnex.models.EditFile;
import org.mian.gitnex.models.Emails;
@@ -321,6 +322,9 @@ public interface ApiInterface {
@POST("repos/{owner}/{repo}/pulls/{index}/merge") // merge a pull request
Call mergePullRequest(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int index, @Body MergePullRequest jsonStr);
+ @POST("repos/{owner}/{repo}/pulls") // create a pull request
+ Call createPullRequest(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body CreatePullRequest jsonStr);
+
@GET("repos/{owner}/{repo}/commits") // get all commits
Call> getRepositoryCommits(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("sha") String branchName, @Query("limit") int limit);
diff --git a/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java b/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java
new file mode 100644
index 00000000..91c4b074
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java
@@ -0,0 +1,36 @@
+package org.mian.gitnex.models;
+
+import java.util.ArrayList;
+
+/**
+ * Author M M Arif
+ */
+
+public class CreatePullRequest {
+
+ private String title;
+ private String body;
+ private String assignee;
+ private String base;
+ private String head;
+ private int milestone;
+ private String due_date;
+ private String message;
+
+ private ArrayList assignees;
+ private ArrayList labels;
+
+ public CreatePullRequest(String title, String body, String assignee, String base, String head, int milestone, String due_date, ArrayList assignees, ArrayList labels) {
+
+ this.title = title;
+ this.body = body;
+ this.assignee = assignee;
+ this.base = base; // merge into branch
+ this.head = head; // pull from branch
+ this.milestone = milestone;
+ this.due_date = due_date;
+ this.assignees = assignees;
+ this.labels = labels;
+ }
+
+}
diff --git a/app/src/main/java/org/mian/gitnex/models/Labels.java b/app/src/main/java/org/mian/gitnex/models/Labels.java
index 0569a8f9..87ca1aaa 100644
--- a/app/src/main/java/org/mian/gitnex/models/Labels.java
+++ b/app/src/main/java/org/mian/gitnex/models/Labels.java
@@ -21,6 +21,11 @@ public class Labels {
this.labels = labels;
}
+ public Labels(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
public int getId() {
return id;
}
diff --git a/app/src/main/res/layout/activity_create_pr.xml b/app/src/main/res/layout/activity_create_pr.xml
new file mode 100644
index 00000000..72dae40a
--- /dev/null
+++ b/app/src/main/res/layout/activity_create_pr.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/bottom_sheet_repo.xml b/app/src/main/res/layout/bottom_sheet_repo.xml
index 877eafa9..b0767268 100644
--- a/app/src/main/res/layout/bottom_sheet_repo.xml
+++ b/app/src/main/res/layout/bottom_sheet_repo.xml
@@ -41,6 +41,18 @@
android:textColor="?attr/primaryTextColor"
android:textSize="16sp" />
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/custom_labels_selection_dialog.xml b/app/src/main/res/layout/custom_labels_selection_dialog.xml
new file mode 100644
index 00000000..01fd2877
--- /dev/null
+++ b/app/src/main/res/layout/custom_labels_selection_dialog.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a1f0e0e3..b94a917b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -55,6 +55,7 @@
Explore
Gitea Administration
Manage Accounts
+ New Pull Request
Demo repo
@@ -691,4 +692,13 @@
New owner is required
There is a problem with the owner name. Make sure that the new owner exists
+ Merge Into
+ Pull From
+ These branches are equal. There is no need to create a pull request
+ Merge into branch is required
+ Pull from branch is required
+ Title is required
+ Pull Request created successfully
+ A pull request between these branches already exists
+