diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3d0157b8..2860acff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
+
+ android:theme="@style/AppTheme.NoActionBar" />
@@ -68,7 +72,5 @@
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java
new file mode 100644
index 00000000..32c3cb4b
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java
@@ -0,0 +1,258 @@
+package org.mian.gitnex.activities;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.hendraanggrian.appcompat.socialview.Mention;
+import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
+import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.models.Collaborators;
+import org.mian.gitnex.models.MergePullRequest;
+import org.mian.gitnex.util.AppUtil;
+import org.mian.gitnex.util.TinyDB;
+import java.util.List;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class MergePullRequestActivity extends AppCompatActivity {
+
+ public ImageView closeActivity;
+ private View.OnClickListener onClickListener;
+
+ final Context ctx = this;
+
+ private SocialAutoCompleteTextView mergePR;
+ private ArrayAdapter defaultMentionAdapter;
+ private Button mergeButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_merge_pull_request);
+
+ boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
+ TinyDB tinyDb = new TinyDB(getApplicationContext());
+
+ mergePR = findViewById(R.id.mergePR);
+ mergePR.setShowSoftInputOnFocus(true);
+
+ defaultMentionAdapter = new MentionArrayAdapter<>(this);
+ loadCollaboratorsList();
+
+ mergePR.setMentionAdapter(defaultMentionAdapter);
+
+ closeActivity = findViewById(R.id.close);
+ TextView toolbar_title = findViewById(R.id.toolbar_title);
+
+ if(!tinyDb.getString("issueTitle").isEmpty()) {
+ toolbar_title.setText(tinyDb.getString("issueTitle"));
+ }
+
+ initCloseListener();
+ closeActivity.setOnClickListener(onClickListener);
+
+ mergeButton = findViewById(R.id.mergeButton);
+
+ if(!connToInternet) {
+
+ disableProcessButton();
+
+ } else {
+
+ mergeButton.setOnClickListener(mergePullRequest);
+
+ }
+
+ }
+
+ public void loadCollaboratorsList() {
+
+ final TinyDB tinyDb = new TinyDB(getApplicationContext());
+
+ final String instanceUrl = tinyDb.getString("instanceUrl");
+ final String loginUid = tinyDb.getString("loginUid");
+ final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
+ String repoFullName = tinyDb.getString("repoFullName");
+ String[] parts = repoFullName.split("/");
+ final String repoOwner = parts[0];
+ final String repoName = parts[1];
+
+ Call> call = RetrofitClient
+ .getInstance(instanceUrl, getApplicationContext())
+ .getApiInterface()
+ .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if (response.isSuccessful()) {
+
+ assert response.body() != null;
+ String fullName = "";
+ for (int i = 0; i < response.body().size(); i++) {
+ if(!response.body().get(i).getFull_name().equals("")) {
+ fullName = response.body().get(i).getFull_name();
+ }
+ defaultMentionAdapter.add(
+ new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
+ }
+
+ }
+ else {
+
+ Log.i("onResponse", String.valueOf(response.code()));
+
+ }
+
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Log.i("onFailure", t.toString());
+ }
+
+ });
+ }
+
+ private void initCloseListener() {
+ onClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ };
+ }
+
+ private View.OnClickListener mergePullRequest = new View.OnClickListener() {
+ public void onClick(View v) {
+ processMergePullRequest();
+ }
+ };
+
+ private void processMergePullRequest() {
+
+ String mergePRDT = mergePR.getText().toString();
+ boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
+
+ if(!connToInternet) {
+
+ Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
+ return;
+
+ }
+
+ disableProcessButton();
+ String doWhat = "merge";
+ mergeFunction(doWhat, mergePRDT);
+
+ }
+
+ private void mergeFunction(String doWhat, String mergePRDT) {
+
+ final TinyDB tinyDb = new TinyDB(getApplicationContext());
+
+ final String instanceUrl = tinyDb.getString("instanceUrl");
+ final String loginUid = tinyDb.getString("loginUid");
+ final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
+ String repoFullName = tinyDb.getString("repoFullName");
+ String[] parts = repoFullName.split("/");
+ final String repoOwner = parts[0];
+ final String repoName = parts[1];
+ final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
+
+ MergePullRequest mergePR = new MergePullRequest(doWhat, mergePRDT, null);
+
+ Call call = RetrofitClient
+ .getInstance(instanceUrl, getApplicationContext())
+ .getApiInterface()
+ .mergePullRequest(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR);
+
+ call.enqueue(new Callback() {
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ if(response.code() == 200) {
+
+ Toasty.info(getApplicationContext(), getString(R.string.mergePRSuccessMsg));
+ tinyDb.putBoolean("prMerged", true);
+ tinyDb.putBoolean("resumePullRequests", true);
+ finish();
+
+ }
+ else if(response.code() == 401) {
+
+ enableProcessButton();
+ AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+
+ }
+ else if(response.code() == 404) {
+
+ enableProcessButton();
+ Toasty.info(getApplicationContext(), getString(R.string.mergePR404ErrorMsg));
+
+ }
+ else {
+
+ enableProcessButton();
+ Toasty.info(getApplicationContext(), getString(R.string.genericError));
+
+ }
+
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ Log.e("onFailure", t.toString());
+ enableProcessButton();
+ }
+
+ });
+
+ }
+
+ private void disableProcessButton() {
+
+ mergeButton.setEnabled(false);
+ GradientDrawable shape = new GradientDrawable();
+ shape.setCornerRadius( 8 );
+ shape.setColor(getResources().getColor(R.color.hintColor));
+ mergeButton.setBackground(shape);
+
+ }
+
+ private void enableProcessButton() {
+
+ mergeButton.setEnabled(true);
+ GradientDrawable shape = new GradientDrawable();
+ shape.setCornerRadius( 8 );
+ shape.setColor(getResources().getColor(R.color.btnBackground));
+ mergeButton.setBackground(shape);
+
+ }
+
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java
index 8b252ce7..80b64581 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java
@@ -260,7 +260,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
- searchView.setQueryHint(getContext().getString(R.string.strFilter));
+ //searchView.setQueryHint(getContext().getString(R.string.search));
/*if(!connToInternet) {
return;
diff --git a/app/src/main/java/org/mian/gitnex/fragments/SingleIssueBottomSheetFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SingleIssueBottomSheetFragment.java
index 3e4016b2..02398549 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/SingleIssueBottomSheetFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/SingleIssueBottomSheetFragment.java
@@ -13,6 +13,7 @@ import org.mian.gitnex.activities.AddRemoveAssigneesActivity;
import org.mian.gitnex.activities.AddRemoveLabelsActivity;
import org.mian.gitnex.activities.EditIssueActivity;
import org.mian.gitnex.activities.FileDiffActivity;
+import org.mian.gitnex.activities.MergePullRequestActivity;
import org.mian.gitnex.activities.ReplyToIssueActivity;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.util.TinyDB;
@@ -44,6 +45,7 @@ public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees);
TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl);
TextView openFilesDiff = v.findViewById(R.id.openFilesDiff);
+ TextView mergePullRequest = v.findViewById(R.id.mergePullRequest);
replyToIssue.setOnClickListener(new View.OnClickListener() {
@Override
@@ -56,14 +58,40 @@ public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
});
if(tinyDB.getString("issueType").equals("pr")) {
+
editIssue.setText(R.string.editPrText);
copyIssueUrl.setText(R.string.copyPrUrlText);
+ if(tinyDB.getBoolean("prMerged")) {
+ mergePullRequest.setVisibility(View.GONE);
+ }
+ else {
+ mergePullRequest.setVisibility(View.VISIBLE);
+ }
+
if(tinyDB.getString("repoType").equals("public")) {
openFilesDiff.setVisibility(View.VISIBLE);
}
+ else {
+ openFilesDiff.setVisibility(View.GONE);
+ }
}
+ else {
+
+ mergePullRequest.setVisibility(View.GONE);
+
+ }
+
+ mergePullRequest.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ startActivity(new Intent(getContext(), MergePullRequestActivity.class));
+ dismiss();
+
+ }
+ });
openFilesDiff.setOnClickListener(new View.OnClickListener() {
@Override
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 61bd89a2..deb2b053 100644
--- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
+++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
@@ -5,6 +5,7 @@ import org.mian.gitnex.models.AddEmail;
import org.mian.gitnex.models.Branches;
import org.mian.gitnex.models.ExploreRepositories;
import org.mian.gitnex.models.Files;
+import org.mian.gitnex.models.MergePullRequest;
import org.mian.gitnex.models.NewFile;
import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.models.UpdateIssueAssignee;
@@ -31,7 +32,6 @@ import org.mian.gitnex.models.UserSearch;
import org.mian.gitnex.models.UserTokens;
import org.mian.gitnex.models.WatchRepository;
import java.util.List;
-
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
@@ -257,4 +257,6 @@ public interface ApiInterface {
@GET("{owner}/{repo}/pulls/{filename}") // get pull diff file contents
Call getFileDiffContents(@Path("owner") String owner, @Path("repo") String repo, @Path("filename") String fileName);
+ @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);
}
diff --git a/app/src/main/java/org/mian/gitnex/models/MergePullRequest.java b/app/src/main/java/org/mian/gitnex/models/MergePullRequest.java
new file mode 100644
index 00000000..6c59f636
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/models/MergePullRequest.java
@@ -0,0 +1,19 @@
+package org.mian.gitnex.models;
+
+/**
+ * Author M M Arif
+ */
+
+public class MergePullRequest {
+
+ private String Do;
+ private String MergeMessageField;
+ private String MergeTitleField;
+
+ public MergePullRequest(String Do, String MergeMessageField, String MergeTitleField) {
+ this.Do = Do;
+ this.MergeMessageField = MergeMessageField;
+ this.MergeTitleField = MergeTitleField;
+ }
+
+}
diff --git a/app/src/main/res/layout/activity_merge_pull_request.xml b/app/src/main/res/layout/activity_merge_pull_request.xml
new file mode 100644
index 00000000..cd079e0f
--- /dev/null
+++ b/app/src/main/res/layout/activity_merge_pull_request.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/single_issue_bottom_sheet_layout.xml b/app/src/main/res/layout/single_issue_bottom_sheet_layout.xml
index adaa6783..ad57159c 100644
--- a/app/src/main/res/layout/single_issue_bottom_sheet_layout.xml
+++ b/app/src/main/res/layout/single_issue_bottom_sheet_layout.xml
@@ -42,6 +42,18 @@
android:textSize="16sp"
android:padding="16dp" />
+
+
%1$s File Changed
-%1$s
Files Changed
+ Merge Pull Request
+ Merge
+ Merge may fail if you are not authorized to merge this Pull Request.
+ Merge comment
+ Pull Request was merged successfully
+ Pull Request is not available for merge