From 57f0d23ef0da7e98ea606d3515ad5623d9abd13d Mon Sep 17 00:00:00 2001 From: M M Arif Date: Fri, 9 Oct 2020 17:47:52 +0200 Subject: [PATCH] New popup for labels/assignees (#723) Preventing lists to store duplicate collaborators (#726) Using login instead of id. Merge branch 'new-popup-labels-assigness' of https://codeberg.org/gitnex/GitNex into new-popup-labels-assigness To prevent lists storing duplicate Collaborators Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/726 Add current logged user to list Change to collection Fix depricated handler calls Change to List and better naming Move to actions Merge branch 'master' into new-popup-labels-assigness Add assignees popup and remove multi select update to view binding add/remove labels in edit issue remove org call Add org members to assignees list Add assignees adapter Add color to labels Refactor and add new labels popup Clean up build libs Co-authored-by: opyale Co-authored-by: M M Arif Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/723 Reviewed-by: opyale --- README.md | 2 - app/build.gradle | 1 - app/src/main/AndroidManifest.xml | 6 - .../mian/gitnex/actions/AssigneesActions.java | 122 +++++ .../mian/gitnex/actions/LabelsActions.java | 116 ++++ .../AddRemoveAssigneesActivity.java | 294 ---------- .../activities/AddRemoveLabelsActivity.java | 308 ----------- .../activities/CreateIssueActivity.java | 507 ++++++------------ .../activities/CreatePullRequestActivity.java | 65 +-- .../activities/IssueDetailActivity.java | 476 +++++++++++----- .../mian/gitnex/activities/LoginActivity.java | 9 - .../gitnex/adapters/AssigneesListAdapter.java | 130 +++++ .../gitnex/adapters/LabelsListAdapter.java | 49 +- .../gitnex/adapters/MutliSelectAdapter.java | 190 ------- .../BottomSheetSingleIssueFragment.java | 37 +- .../gitnex/helpers/MultiSelectDialog.java | 318 ----------- .../mian/gitnex/interfaces/ApiInterface.java | 3 + .../org/mian/gitnex/models/Collaborators.java | 29 + .../org/mian/gitnex/models/CreateIssue.java | 4 +- .../mian/gitnex/models/CreatePullRequest.java | 8 +- .../java/org/mian/gitnex/models/Labels.java | 9 +- .../layout/activity_add_remove_assignees.xml | 8 - .../res/layout/activity_add_remove_labels.xml | 8 - .../main/res/layout/activity_create_issue.xml | 274 +++++----- app/src/main/res/layout/activity_login.xml | 16 - .../main/res/layout/custom_assignees_list.xml | 46 ++ .../custom_assignees_selection_dialog.xml | 101 ++++ .../main/res/layout/custom_labels_list.xml | 33 +- .../main/res/layout/custom_multi_select.xml | 116 ---- app/src/main/res/layout/multi_select_item.xml | 28 - app/src/main/res/values/strings.xml | 2 +- build.gradle | 2 +- 32 files changed, 1304 insertions(+), 2013 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java create mode 100644 app/src/main/java/org/mian/gitnex/actions/LabelsActions.java delete mode 100644 app/src/main/java/org/mian/gitnex/activities/AddRemoveAssigneesActivity.java delete mode 100644 app/src/main/java/org/mian/gitnex/activities/AddRemoveLabelsActivity.java create mode 100644 app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java delete mode 100644 app/src/main/java/org/mian/gitnex/adapters/MutliSelectAdapter.java delete mode 100644 app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java delete mode 100644 app/src/main/res/layout/activity_add_remove_assignees.xml delete mode 100644 app/src/main/res/layout/activity_add_remove_labels.xml create mode 100644 app/src/main/res/layout/custom_assignees_list.xml create mode 100644 app/src/main/res/layout/custom_assignees_selection_dialog.xml delete mode 100644 app/src/main/res/layout/custom_multi_select.xml delete mode 100644 app/src/main/res/layout/multi_select_item.xml diff --git a/README.md b/README.md index f9f3f54f..e6ac43f6 100644 --- a/README.md +++ b/README.md @@ -72,13 +72,11 @@ Thanks to all the open source libraries, contributors and donators. - Retrofit - Gson - Okhttp -- ViHtarb/tooltip - Picasso - Markwon - Prettytime - Amulyakhare/textdrawable - Vdurmont/emoji-java -- Abumoallim/android-multi-select-dialog - Pes/materialcolorpicker - Hendraanggrian/socialview - HamidrezaAmz/BreadcrumbsView diff --git a/app/build.gradle b/app/build.gradle index 1fda9330..54a3b468 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,7 +66,6 @@ dependencies { testImplementation "junit:junit:4.13" androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - implementation "com.github.vihtarb:tooltip:0.2.0" implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation "com.google.code.gson:gson:2.8.6" implementation "com.squareup.picasso:picasso:2.71828" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d7a57f36..4b656f12 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,15 +31,9 @@ android:name=".activities.RepoStargazersActivity" android:theme="@style/AppTheme.NoActionBar" /> - - diff --git a/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java b/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java new file mode 100644 index 00000000..c013e970 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java @@ -0,0 +1,122 @@ +package org.mian.gitnex.actions; + +import android.app.Dialog; +import android.content.Context; +import android.util.Log; +import android.view.View; +import androidx.annotation.NonNull; +import org.mian.gitnex.R; +import org.mian.gitnex.adapters.AssigneesListAdapter; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.models.Collaborators; +import org.mian.gitnex.models.Issues; +import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; + +/** + * Author M M Arif + */ + +public class AssigneesActions { + + public static void getCurrentIssueAssignees(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List currentAssignees) { + + Call callSingleIssueLabels = RetrofitClient + .getInstance(instanceUrl, ctx) + .getApiInterface() + .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + + callSingleIssueLabels.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + if(response.code() == 200) { + + Issues issueAssigneesList = response.body(); + assert issueAssigneesList != null; + + if (issueAssigneesList.getAssignees() != null) { + + if(issueAssigneesList.getAssignees().size() > 0) { + + for(int i = 0; i < issueAssigneesList.getAssignees().size(); i++) { + + currentAssignees.add(issueAssigneesList.getAssignees().get(i).getLogin()); + } + } + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + + }); + } + + public static void getRepositoryAssignees(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List assigneesList, Dialog dialogAssignees, AssigneesListAdapter assigneesAdapter, CustomAssigneesSelectionDialogBinding assigneesBinding) { + + TinyDB tinyDB = new TinyDB(ctx); + + Call> call = RetrofitClient + .getInstance(instanceUrl, ctx) + .getApiInterface() + .getCollaborators(instanceToken, repoOwner, repoName); + + call.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { + + assigneesList.clear(); + List assigneesList_ = response.body(); + + assigneesBinding.progressBar.setVisibility(View.GONE); + assigneesBinding.dialogFrame.setVisibility(View.VISIBLE); + + if (response.code() == 200) { + + assert assigneesList_ != null; + + if(assigneesList_.size() > 0) { + + dialogAssignees.show(); + + assigneesList.add(new Collaborators(tinyDB.getString("userFullname"), tinyDB.getString("loginUid"), tinyDB.getString("userAvatar"))); + assigneesList.addAll(assigneesList_); + } + else { + + dialogAssignees.dismiss(); + Toasty.warning(ctx, ctx.getResources().getString(R.string.noAssigneesFound)); + } + + assigneesBinding.assigneesRecyclerView.setAdapter(assigneesAdapter); + + } + else { + + Toasty.error(ctx, ctx.getResources().getString(R.string.genericError)); + } + + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); + } + }); + + } + +} diff --git a/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java b/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java new file mode 100644 index 00000000..e6338617 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java @@ -0,0 +1,116 @@ +package org.mian.gitnex.actions; + +import android.app.Dialog; +import android.content.Context; +import android.util.Log; +import android.view.View; +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.CustomLabelsSelectionDialogBinding; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.models.Labels; +import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; + +/** + * Author M M Arif + */ + +public class LabelsActions { + + public static void getCurrentIssueLabels(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List currentLabelsIds) { + + Call> callSingleIssueLabels = RetrofitClient + .getInstance(instanceUrl, ctx) + .getApiInterface() + .getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + + callSingleIssueLabels.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { + + if(response.code() == 200) { + + List issueLabelsList = response.body(); + + assert issueLabelsList != null; + + if(issueLabelsList.size() > 0) { + + for (int i = 0; i < issueLabelsList.size(); i++) { + + currentLabelsIds.add(issueLabelsList.get(i).getId()); + } + } + + } + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + + }); + } + + public static void getRepositoryLabels(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List labelsList, Dialog dialogLabels, LabelsListAdapter labelsAdapter, CustomLabelsSelectionDialogBinding labelsBinding) { + + 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) { + + dialogLabels.show(); + + labelsList.addAll(labelsList_); + } + else { + + dialogLabels.dismiss(); + Toasty.warning(ctx, ctx.getResources().getString(R.string.noLabelsFound)); + } + + labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter); + + } + else { + + Toasty.error(ctx, ctx.getResources().getString(R.string.genericError)); + } + + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); + } + }); + + } + +} diff --git a/app/src/main/java/org/mian/gitnex/activities/AddRemoveAssigneesActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddRemoveAssigneesActivity.java deleted file mode 100644 index af6d441a..00000000 --- a/app/src/main/java/org/mian/gitnex/activities/AddRemoveAssigneesActivity.java +++ /dev/null @@ -1,294 +0,0 @@ -package org.mian.gitnex.activities; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.util.Log; -import androidx.annotation.NonNull; -import com.google.gson.JsonElement; -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.MultiSelectDialog; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.models.Collaborators; -import org.mian.gitnex.models.Issues; -import org.mian.gitnex.models.MultiSelectModel; -import org.mian.gitnex.models.UpdateIssueAssignees; -import java.util.ArrayList; -import java.util.List; -import retrofit2.Call; -import retrofit2.Callback; - -/** - * Author M M Arif - */ - -public class AddRemoveAssigneesActivity extends BaseActivity { - - private ArrayList listOfCollaborators = new ArrayList<>(); - private ArrayList issueAssigneesIds = new ArrayList<>(); - private Boolean assigneesFlag = false; - private MultiSelectDialog multiSelectDialogAssignees; - final Context ctx = this; - private Context appCtx; - - @Override - protected int getLayoutResourceId(){ - return R.layout.activity_add_remove_assignees; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - //supportRequestWindowFeature(Window.FEATURE_NO_TITLE); - - getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); - - TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - - getAssignees(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); - - } - - private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { - - final TinyDB tinyDb = new TinyDB(appCtx); - - Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull final Call> call, @NonNull final retrofit2.Response> response) { - - if(response.isSuccessful()) { - if(response.code() == 200) { - - final List collaboratorsList_ = response.body(); - - assert collaboratorsList_ != null; - if(collaboratorsList_.size() > 0) { - for (int i = 0; i < collaboratorsList_.size(); i++) { - - listOfCollaborators.add(new MultiSelectModel(collaboratorsList_.get(i).getId(), collaboratorsList_.get(i).getUsername().trim())); - - } - } - - // get current issue assignees - Call callSingleIssueAssignees = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); - - callSingleIssueAssignees.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - - if(response.code() == 200) { - - Issues issueAssigneesList = response.body(); - - assert issueAssigneesList != null; - if (issueAssigneesList.getAssignees() != null) { - if (issueAssigneesList.getAssignees().size() > 0) { - for (int i = 0; i < issueAssigneesList.getAssignees().size(); i++) { - - issueAssigneesIds.add(issueAssigneesList.getAssignees().get(i).getId()); - - if(issueAssigneesList.getAssignees().get(i).getUsername().equals(loginUid)) { - listOfCollaborators.add(new MultiSelectModel(issueAssigneesList.getAssignees().get(i).getId(), issueAssigneesList.getAssignees().get(i).getUsername().trim())); - } - - } - assigneesFlag = true; - } - } - else { - listOfCollaborators.add(new MultiSelectModel(tinyDb.getInt("userId"), loginUid)); - } - - if(assigneesFlag) { - - multiSelectDialogAssignees = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.saveButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .preSelectIDsList(issueAssigneesIds) - .setMaxSelectionLimit(listOfCollaborators.size()) - .multiSelectList(listOfCollaborators) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - Log.i("selectedNames", String.valueOf(selectedNames)); - - updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); - tinyDb.putBoolean("singleIssueUpdate", true); - CloseActivity(); - } - - @Override - public void onCancel() { - CloseActivity(); - } - }); - - } - else { - - multiSelectDialogAssignees = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.saveButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .setMaxSelectionLimit(listOfCollaborators.size()) - .multiSelectList(listOfCollaborators) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames); - tinyDb.putBoolean("singleIssueUpdate", true); - CloseActivity(); - - } - - @Override - public void onCancel() { - CloseActivity(); - } - }); - - } - - multiSelectDialogAssignees.show(getSupportFragmentManager(), "issueMultiSelectDialog"); - - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - - }); - // get current issue assignees - - } - else if(response.code() == 401) { - - 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() == 403) { - - Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - - } - else if(response.code() == 404) { - - Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - - } - else { - - Toasty.error(ctx, getString(R.string.genericError)); - - } - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - - private void CloseActivity() { - this.finish(); - } - - private void updateIssueAssignees(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, int issueIndex, List issueAssigneesList) { - - UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(issueAssigneesList); - - Call call3; - - call3 = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson); - - call3.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response2) { - - if(response2.code() == 201) { - - Toasty.success(ctx, ctx.getString(R.string.assigneesUpdated)); - - } - else if(response2.code() == 401) { - - 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(response2.code() == 403) { - - Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - - } - else if(response2.code() == 404) { - - Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - - } - else { - - Toasty.error(ctx, getString(R.string.genericError)); - - } - - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - -} diff --git a/app/src/main/java/org/mian/gitnex/activities/AddRemoveLabelsActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddRemoveLabelsActivity.java deleted file mode 100644 index 3bf38964..00000000 --- a/app/src/main/java/org/mian/gitnex/activities/AddRemoveLabelsActivity.java +++ /dev/null @@ -1,308 +0,0 @@ -package org.mian.gitnex.activities; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.util.Log; -import androidx.annotation.NonNull; -import com.google.gson.JsonElement; -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.MultiSelectDialog; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.models.Labels; -import org.mian.gitnex.models.MultiSelectModel; -import java.util.ArrayList; -import java.util.List; -import retrofit2.Call; -import retrofit2.Callback; - -/** - * Author M M Arif - */ - -public class AddRemoveLabelsActivity extends BaseActivity { - - private ArrayList listOfLabels = new ArrayList<>(); - private ArrayList issueLabelIds = new ArrayList<>(); - private Boolean labelsFlag = false; - private MultiSelectDialog multiSelectDialogLabels; - final Context ctx = this; - private Context appCtx; - - @Override - protected int getLayoutResourceId(){ - return R.layout.activity_add_remove_labels; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - //supportRequestWindowFeature(Window.FEATURE_NO_TITLE); - - getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); - - TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - - getLabels(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); - - } - - private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) { - - final TinyDB tinyDb = new TinyDB(appCtx); - - Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getlabels(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 labelsList_ = response.body(); - - assert labelsList_ != null; - if(labelsList_.size() > 0) { - for (int i = 0; i < labelsList_.size(); i++) { - - listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim())); - - } - } - - // get current issue labels - Call> callSingleIssueLabels = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); - - callSingleIssueLabels.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { - - if(response.code() == 200) { - - List issueLabelsList = response.body(); - - assert issueLabelsList != null; - if(issueLabelsList.size() > 0) { - for (int i = 0; i < issueLabelsList.size(); i++) { - - issueLabelIds.add(issueLabelsList.get(i).getId()); - - } - labelsFlag = true; - } - - if(labelsFlag) { - - multiSelectDialogLabels = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectLabelsListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.saveButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .preSelectIDsList(issueLabelIds) - .setMaxSelectionLimit(listOfLabels.size()) - .multiSelectList(listOfLabels) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - String labelIds = selectedIds.toString(); - int[] integers; - if (selectedIds.size() > 0) { - - String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(","); - integers = new int[items.length]; - for (int i = 0; i < integers.length; i++) { - integers[i] = Integer.parseInt(items[i]); - } - - } - else { - integers = new int[0]; - } - - updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); - tinyDb.putBoolean("singleIssueUpdate", true); - CloseActivity(); - } - - @Override - public void onCancel() { - CloseActivity(); - } - }); - - } - else { - - multiSelectDialogLabels = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectLabelsListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.saveButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .setMaxSelectionLimit(listOfLabels.size()) - .multiSelectList(listOfLabels) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - String labelIds = selectedIds.toString(); - int[] integers; - if (selectedIds.size() > 0) { - - String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(","); - integers = new int[items.length]; - for (int i = 0; i < integers.length; i++) { - integers[i] = Integer.parseInt(items[i]); - } - - } - else { - integers = new int[0]; - } - - updateIssueLabels(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid); - tinyDb.putBoolean("singleIssueUpdate", true); - CloseActivity(); - - } - - @Override - public void onCancel() { - CloseActivity(); - } - }); - - } - - multiSelectDialogLabels.show(getSupportFragmentManager(), "issueMultiSelectDialog"); - - } - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - - }); - // get current issue labels - - } - else if(response.code() == 401) { - - 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() == 403) { - - Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - - } - else if(response.code() == 404) { - - Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - - } - else { - - Toasty.error(ctx, getString(R.string.genericError)); - - } - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - - private void updateIssueLabels(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, int issueIndex, int[] issueLabels, String loginUid) { - - Labels patchIssueLabels = new Labels(issueLabels); - - Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels); - - call.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - - if(response.code() == 200) { - - Toasty.success(ctx, ctx.getString(R.string.labelsUpdated)); - - } - else if(response.code() == 401) { - - 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() == 403) { - - Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - - } - else if(response.code() == 404) { - - Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - - } - else { - - Toasty.error(ctx, getString(R.string.genericError)); - - } - - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - - private void CloseActivity() { - this.finish(); - } -} diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java index b4cd679d..52e060b1 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java @@ -1,29 +1,29 @@ 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.util.Log; +import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.DatePicker; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.Spinner; -import android.widget.TextView; import androidx.annotation.NonNull; import com.google.gson.JsonElement; -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.actions.AssigneesActions; +import org.mian.gitnex.actions.LabelsActions; +import org.mian.gitnex.adapters.AssigneesListAdapter; +import org.mian.gitnex.adapters.LabelsListAdapter; import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.databinding.ActivityCreateIssueBinding; +import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding; +import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.MultiSelectDialog; import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; @@ -32,45 +32,50 @@ import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.Labels; import org.mian.gitnex.models.Milestones; -import org.mian.gitnex.models.MultiSelectModel; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.List; +import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; -import retrofit2.Response; /** * Author M M Arif */ -public class CreateIssueActivity extends BaseActivity implements View.OnClickListener { +public class CreateIssueActivity extends BaseActivity implements View.OnClickListener, LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener { + private ActivityCreateIssueBinding viewBinding; + private CustomLabelsSelectionDialogBinding labelsBinding; + private CustomAssigneesSelectionDialogBinding assigneesBinding; private View.OnClickListener onClickListener; - MultiSelectDialog multiSelectDialog; - MultiSelectDialog multiSelectDialogLabels; - private TextView assigneesList; - private TextView newIssueLabels; - private TextView newIssueDueDate; - private Spinner newIssueMilestoneSpinner; - private EditText newIssueTitle; - private SocialAutoCompleteTextView newIssueDescription; - private Button createNewIssueButton; - private TextView labelsIdHolder; - private boolean assigneesFlag; - private boolean labelsFlag; final Context ctx = this; private Context appCtx; + private TinyDB tinyDb; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private Dialog dialogLabels; + private Dialog dialogAssignees; + private String labelsSetter; + private String assigneesSetter; + private int milestoneId; - List milestonesList = new ArrayList<>(); - ArrayList listOfAssignees = new ArrayList<>(); - ArrayList listOfLabels= new ArrayList<>(); - private ArrayAdapter defaultMentionAdapter; + private String instanceUrl; + private String loginUid; + private String instanceToken; + private String repoOwner; + private String repoName; + + private LabelsListAdapter labelsAdapter; + private AssigneesListAdapter assigneesAdapter; + + private List labelsIds = new ArrayList<>(); + private List labelsList = new ArrayList<>(); + private List milestonesList = new ArrayList<>(); + private List assigneesList = new ArrayList<>(); + private List assigneesListData = new ArrayList<>(); @Override - protected int getLayoutResourceId(){ + protected int getLayoutResourceId() { return R.layout.activity_create_issue; } @@ -79,20 +84,24 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis super.onCreate(savedInstanceState); appCtx = getApplicationContext(); + tinyDb = new TinyDB(appCtx); + + viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); + instanceUrl = tinyDb.getString("instanceUrl"); + loginUid = tinyDb.getString("loginUid"); final String loginFullName = tinyDb.getString("userFullname"); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + 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")) { @@ -100,71 +109,113 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } - ImageView closeActivity = findViewById(R.id.close); - assigneesList = findViewById(R.id.newIssueAssigneesList); - newIssueLabels = findViewById(R.id.newIssueLabels); - newIssueDueDate = findViewById(R.id.newIssueDueDate); - createNewIssueButton = findViewById(R.id.createNewIssueButton); - newIssueTitle = findViewById(R.id.newIssueTitle); - newIssueDescription = findViewById(R.id.newIssueDescription); - labelsIdHolder = findViewById(R.id.labelsIdHolder); - - newIssueTitle.requestFocus(); + viewBinding.newIssueTitle.requestFocus(); assert imm != null; - imm.showSoftInput(newIssueTitle, InputMethodManager.SHOW_IMPLICIT); + imm.showSoftInput(viewBinding.newIssueTitle, InputMethodManager.SHOW_IMPLICIT); - defaultMentionAdapter = new MentionArrayAdapter<>(this); - loadCollaboratorsList(); - - newIssueDescription.setMentionAdapter(defaultMentionAdapter); + labelsAdapter = new LabelsListAdapter(labelsList, CreateIssueActivity.this, labelsIds); + assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, CreateIssueActivity.this, assigneesListData); initCloseListener(); - closeActivity.setOnClickListener(onClickListener); + viewBinding.close.setOnClickListener(onClickListener); - assigneesList.setOnClickListener(this); - newIssueLabels.setOnClickListener(this); - newIssueDueDate.setOnClickListener(this); + viewBinding.newIssueAssigneesList.setOnClickListener(this); + viewBinding.newIssueLabels.setOnClickListener(this); + viewBinding.newIssueDueDate.setOnClickListener(this); - newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner); getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); - getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid); - getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName); - disableProcessButton(); + viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> + showLabels() + ); + + viewBinding.newIssueAssigneesList.setOnClickListener(newIssueAssigneesList -> + showAssignees() + ); + if(!connToInternet) { - createNewIssueButton.setEnabled(false); + viewBinding.createNewIssueButton.setEnabled(false); } else { - createNewIssueButton.setOnClickListener(this); + viewBinding.createNewIssueButton.setOnClickListener(this); } } + @Override + public void assigneesInterface(List data) { + + assigneesSetter = String.valueOf(data); + viewBinding.newIssueAssigneesList.setText(assigneesSetter.replace("]", "").replace("[", "")); + assigneesListData = data; + } + + @Override + public void labelsInterface(List data) { + + labelsSetter = String.valueOf(data); + viewBinding.newIssueLabels.setText(labelsSetter.replace("]", "").replace("[", "")); + } + + @Override + public void labelsIdsInterface(List data) { + + labelsIds = data; + } + + private void showAssignees() { + + dialogAssignees = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); + + if (dialogAssignees.getWindow() != null) { + + dialogAssignees.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + } + + assigneesBinding = CustomAssigneesSelectionDialogBinding.inflate(LayoutInflater.from(ctx)); + + View view = assigneesBinding.getRoot(); + dialogAssignees.setContentView(view); + + assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> + dialogAssignees.dismiss() + ); + + AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); + } + + 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(labelsBinding_ -> + dialogLabels.dismiss() + ); + + LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); + } + private void processNewIssue() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - Milestones mModel = (Milestones) newIssueMilestoneSpinner.getSelectedItem(); - - int newIssueMilestoneIdForm = mModel.getId(); - String newIssueTitleForm = newIssueTitle.getText().toString(); - String newIssueDescriptionForm = newIssueDescription.getText().toString(); - String newIssueAssigneesListForm = assigneesList.getText().toString(); - //String newIssueLabelsForm = newIssueLabels.getText().toString(); - String newIssueDueDateForm = newIssueDueDate.getText().toString(); - String newIssueLabelsIdHolderForm = labelsIdHolder.getText().toString(); + String newIssueTitleForm = Objects.requireNonNull(viewBinding.newIssueTitle.getText()).toString(); + String newIssueDescriptionForm = Objects.requireNonNull(viewBinding.newIssueDescription.getText()).toString(); + String newIssueDueDateForm = Objects.requireNonNull(viewBinding.newIssueDueDate.getText()).toString(); if(!connToInternet) { @@ -177,101 +228,25 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis Toasty.error(ctx, getString(R.string.issueTitleEmpty)); return; - } - /*if (newIssueDescriptionForm.equals("")) { - - Toasty.error(ctx, getString(R.string.issueDescriptionEmpty)); - return; - - }*/ - if (newIssueDueDateForm.equals("")) { + newIssueDueDateForm = null; - } else { + } + else { + newIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(newIssueDueDateForm))); } - List newIssueAssigneesListForm_ = new ArrayList<>(Arrays.asList(newIssueAssigneesListForm.split(","))); - - for (int i = 0; i < newIssueAssigneesListForm_.size(); i++) { - newIssueAssigneesListForm_.set(i, newIssueAssigneesListForm_.get(i).trim()); - } - - int[] integers; - if (!newIssueLabelsIdHolderForm.equals("") && !newIssueLabelsIdHolderForm.equals("[]")) { - - String[] items = newIssueLabelsIdHolderForm.replaceAll("\\[", "").replaceAll("]", "").replaceAll("\\s", "").split(","); - integers = new int[items.length]; - for (int i = 0; i < integers.length; i++) { - integers[i] = Integer.parseInt(items[i]); - } - - } - else { - integers = new int[0]; - } - - //Log.i("FormData", String.valueOf(newIssueLabelsForm)); disableProcessButton(); - createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm_, integers); + createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, milestoneId, newIssueTitleForm); } - public void loadCollaboratorsList() { + private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm) { - final TinyDB tinyDb = new TinyDB(appCtx); - - 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, ctx) - .getApiInterface() - .getCollaborators(Authorization.returnAuthentication(ctx, 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 createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm, List newIssueAssigneesListForm, int[] newIssueLabelsForm) { - - CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm, newIssueLabelsForm); + CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, assigneesListData, labelsIds); Call call3; @@ -285,19 +260,14 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response2) { - if(response2.isSuccessful()) { - if(response2.code() == 201) { + if(response2.code() == 201) { - //Log.i("isSuccessful1", String.valueOf(response2.body())); - TinyDB tinyDb = new TinyDB(appCtx); - tinyDb.putBoolean("resumeIssues", true); - - Toasty.success(ctx, getString(R.string.issueCreated)); - enableProcessButton(); - finish(); - - } + TinyDB tinyDb = new TinyDB(appCtx); + tinyDb.putBoolean("resumeIssues", true); + Toasty.success(ctx, getString(R.string.issueCreated)); + enableProcessButton(); + finish(); } else if(response2.code() == 401) { @@ -306,21 +276,19 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { Toasty.error(ctx, getString(R.string.issueCreatedError)); enableProcessButton(); - //Log.i("isSuccessful2", String.valueOf(response2.body())); - } } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); + + Toasty.error(ctx, getString(R.string.genericServerResponseError)); enableProcessButton(); } }); @@ -368,12 +336,16 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis } ArrayAdapter adapter = new ArrayAdapter<>(CreateIssueActivity.this, - R.layout.spinner_item, milestonesList); + R.layout.list_spinner_items, milestonesList); - adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); - newIssueMilestoneSpinner.setAdapter(adapter); + viewBinding.newIssueMilestoneSpinner.setAdapter(adapter); enableProcessButton(); + viewBinding.newIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) -> + + milestoneId = milestonesList.get(position).getId() + ); + } } @@ -381,143 +353,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - } - - private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, String loginFullName) { - - Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getCollaborators(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); - - listOfAssignees.add(new MultiSelectModel(-1, loginFullName)); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { - - if(response.isSuccessful()) { - if(response.code() == 200) { - - List assigneesList_ = response.body(); - - assert assigneesList_ != null; - if(assigneesList_.size() > 0) { - for (int i = 0; i < assigneesList_.size(); i++) { - - /*String assigneesCopy; - if(!assigneesList_.get(i).getFull_name().equals("")) { - assigneesCopy = getString(R.string.dialogAssignessText, assigneesList_.get(i).getFull_name(), assigneesList_.get(i).getLogin()); - } - else { - assigneesCopy = assigneesList_.get(i).getLogin(); - }*/ - listOfAssignees.add(new MultiSelectModel(assigneesList_.get(i).getId(), assigneesList_.get(i).getLogin().trim())); - - } - assigneesFlag = true; - } - - multiSelectDialog = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.okButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .setMaxSelectionLimit(listOfAssignees.size()) - .multiSelectList(listOfAssignees) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - assigneesList.setText(dataString); - - } - - @Override - public void onCancel() { - //Log.d("multiSelect","Dialog cancelled"); - - } - }); - - } - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } - - private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { - - Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getlabels(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 labelsList_ = response.body(); - - assert labelsList_ != null; - if(labelsList_.size() > 0) { - for (int i = 0; i < labelsList_.size(); i++) { - - listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim())); - - } - labelsFlag = true; - } - - multiSelectDialogLabels = new MultiSelectDialog() - .title(getResources().getString(R.string.newIssueSelectLabelsListTitle)) - .titleSize(25) - .positiveText(getResources().getString(R.string.okButton)) - .negativeText(getResources().getString(R.string.cancelButton)) - .setMinSelectionLimit(0) - .setMaxSelectionLimit(listOfLabels.size()) - .multiSelectList(listOfLabels) - .onSubmit(new MultiSelectDialog.SubmitCallbackListener() { - @Override - public void onSelected(List selectedIds, List selectedNames, String dataString) { - - newIssueLabels.setText(dataString.trim()); - labelsIdHolder.setText(selectedIds.toString()); - - } - - @Override - public void onCancel() { - //Log.d("multiSelect","Dialog cancelled"); - - } - }); - - } - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); + Toasty.error(ctx, getString(R.string.genericServerResponseError)); } }); @@ -525,23 +362,8 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis @Override public void onClick(View v) { - if (v == assigneesList) { - if(assigneesFlag) { - multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog"); - } - else { - Toasty.warning(ctx, getResources().getString(R.string.noAssigneesFound)); - } - } - else if (v == newIssueLabels) { - if(labelsFlag) { - multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels"); - } - else { - Toasty.warning(ctx, getResources().getString(R.string.noLabelsFound)); - } - } - else if (v == newIssueDueDate) { + + if (v == viewBinding.newIssueDueDate) { final Calendar c = Calendar.getInstance(); int mYear = c.get(Calendar.YEAR); @@ -549,19 +371,10 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis final int mDay = c.get(Calendar.DAY_OF_MONTH); DatePickerDialog datePickerDialog = new DatePickerDialog(this, - new DatePickerDialog.OnDateSetListener() { - - @Override - public void onDateSet(DatePicker view, int year, - int monthOfYear, int dayOfMonth) { - - newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)); - - } - }, mYear, mMonth, mDay); + (view, year, monthOfYear, dayOfMonth) -> viewBinding.newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay); datePickerDialog.show(); } - else if(v == createNewIssueButton) { + else if(v == viewBinding.createNewIssueButton) { processNewIssue(); } @@ -569,11 +382,11 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis private void disableProcessButton() { - createNewIssueButton.setEnabled(false); + viewBinding.createNewIssueButton.setEnabled(false); } private void enableProcessButton() { - createNewIssueButton.setEnabled(true); + viewBinding.createNewIssueButton.setEnabled(true); } } diff --git a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java index e066deb5..0809b0ba 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java @@ -12,6 +12,7 @@ import android.widget.ArrayAdapter; import android.widget.ImageView; import androidx.annotation.NonNull; import org.mian.gitnex.R; +import org.mian.gitnex.actions.LabelsActions; import org.mian.gitnex.adapters.LabelsListAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.ActivityCreatePrBinding; @@ -48,8 +49,8 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private Dialog dialogLabels; private String labelsSetter; - private ArrayList labelsIds = new ArrayList<>(); - private ArrayList assignees = new ArrayList<>(); + private List labelsIds = new ArrayList<>(); + private List assignees = new ArrayList<>(); private int milestoneId; private String instanceUrl; @@ -96,7 +97,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } - labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this); + labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds); ImageView closeActivity = findViewById(R.id.close); @@ -164,7 +165,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis //Log.e("processPullRequest", String.valueOf(milestoneId)); } - private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, ArrayList assignees) { + private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, List assignees) { CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds); @@ -213,14 +214,14 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis } @Override - public void labelsStringData(ArrayList data) { + public void labelsInterface(List data) { labelsSetter = String.valueOf(data); viewBinding.prLabels.setText(labelsSetter.replace("]", "").replace("[", "")); } @Override - public void labelsIdsData(ArrayList data) { + public void labelsIdsInterface(List data) { labelsIds = data; } @@ -242,57 +243,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis 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(); - + LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); } private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java index 154cacab..901f5f45 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -1,43 +1,48 @@ package org.mian.gitnex.activities; +import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.text.Html; import android.text.Spanned; import android.util.Log; import android.view.Gravity; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.ScrollView; -import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.amulyakhare.textdrawable.TextDrawable; -import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; +import com.google.gson.JsonElement; import com.vdurmont.emoji.EmojiParser; import org.mian.gitnex.R; +import org.mian.gitnex.actions.AssigneesActions; +import org.mian.gitnex.actions.LabelsActions; +import org.mian.gitnex.adapters.AssigneesListAdapter; import org.mian.gitnex.adapters.IssueCommentsAdapter; +import org.mian.gitnex.adapters.LabelsListAdapter; import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.databinding.ActivityIssueDetailBinding; +import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding; +import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.fragments.BottomSheetSingleIssueFragment; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; @@ -48,15 +53,22 @@ import org.mian.gitnex.helpers.LabelWidthCalculator; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.UserMentions; import org.mian.gitnex.helpers.Version; +import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Issues; +import org.mian.gitnex.models.Labels; +import org.mian.gitnex.models.UpdateIssueAssignees; import org.mian.gitnex.models.WatchInfo; import org.mian.gitnex.viewmodels.IssueCommentsViewModel; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Locale; import java.util.Objects; import io.noties.markwon.AbstractMarkwonPlugin; @@ -82,29 +94,36 @@ import retrofit2.Response; * Author M M Arif */ -public class IssueDetailActivity extends BaseActivity { +public class IssueDetailActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener, BottomSheetSingleIssueFragment.BottomSheetListener { - public ImageView closeActivity; private IssueCommentsAdapter adapter; - private RecyclerView mRecyclerView; - private ImageView assigneeAvatar; - private TextView issueTitle; - private TextView issueDescription; - private TextView issueMilestone; - private TextView issueDueDate; - private TextView issueCreatedTime; - private HorizontalScrollView labelsScrollView; - private HorizontalScrollView assigneesScrollView; - private ScrollView scrollViewComments; - private TextView issueModified; - private ExtendedFloatingActionButton createNewComment; final Context ctx = this; private Context appCtx; - private LinearLayout labelsLayout; - private LinearLayout assigneesLayout; - private View divider; - private ProgressBar progressBar; - private ImageView issuePrState; + private TinyDB tinyDb; + + private String instanceUrl; + private String loginUid; + private String instanceToken; + private String repoOwner; + private String repoName; + private int issueIndex; + + private LabelsListAdapter labelsAdapter; + private AssigneesListAdapter assigneesAdapter; + + private List currentLabelsIds = new ArrayList<>(); + private List labelsIds = new ArrayList<>(); + private List labelsList = new ArrayList<>(); + private List assigneesList = new ArrayList<>(); + private List assigneesListData = new ArrayList<>(); + private List currentAssignees = new ArrayList<>(); + + private Dialog dialogLabels; + private Dialog dialogAssignees; + + private CustomLabelsSelectionDialogBinding labelsBinding; + private CustomAssigneesSelectionDialogBinding assigneesBinding; + private ActivityIssueDetailBinding viewBinding; @Override protected int getLayoutResourceId() { @@ -117,80 +136,65 @@ public class IssueDetailActivity extends BaseActivity { super.onCreate(savedInstanceState); appCtx = getApplicationContext(); + tinyDb = new TinyDB(appCtx); - final TinyDB tinyDb = new TinyDB(appCtx); + viewBinding = ActivityIssueDetailBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + instanceUrl = tinyDb.getString("instanceUrl"); + loginUid = tinyDb.getString("loginUid"); + 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 issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); + repoOwner = parts[0]; + repoName = parts[1]; + issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - final SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh); - - assigneeAvatar = findViewById(R.id.assigneeAvatar); - issueTitle = findViewById(R.id.issueTitle); - issueDescription = findViewById(R.id.issueDescription); - issueMilestone = findViewById(R.id.issueMilestone); - issueDueDate = findViewById(R.id.issueDueDate); - issueCreatedTime = findViewById(R.id.issueCreatedTime); - labelsScrollView = findViewById(R.id.labelsScrollView); - assigneesScrollView = findViewById(R.id.assigneesScrollView); - scrollViewComments = findViewById(R.id.scrollViewComments); - issueModified = findViewById(R.id.issueModified); - createNewComment = findViewById(R.id.addNewComment); - labelsLayout = findViewById(R.id.frameLabels); - assigneesLayout = findViewById(R.id.frameAssignees); - divider = findViewById(R.id.divider); - progressBar = findViewById(R.id.progressBar); - issuePrState = findViewById(R.id.issuePrState); - - Toolbar toolbar = findViewById(R.id.toolbar); - TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - - setSupportActionBar(toolbar); + setSupportActionBar(viewBinding.toolbar); Objects.requireNonNull(getSupportActionBar()).setTitle(repoName); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - mRecyclerView = findViewById(R.id.recyclerView); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setNestedScrollingEnabled(false); - mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx)); + viewBinding.recyclerView.setHasFixedSize(true); + viewBinding.recyclerView.setNestedScrollingEnabled(false); + viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); - mRecyclerView.addItemDecoration(dividerItemDecoration); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL); + viewBinding.recyclerView.addItemDecoration(dividerItemDecoration); - createNewComment.setOnClickListener(v -> startActivity(new Intent(ctx, ReplyToIssueActivity.class))); + viewBinding.addNewComment.setOnClickListener(v -> startActivity(new Intent(ctx, ReplyToIssueActivity.class))); + + labelsAdapter = new LabelsListAdapter(labelsList, IssueDetailActivity.this, currentLabelsIds); + assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, IssueDetailActivity.this, currentAssignees); + LabelsActions.getCurrentIssueLabels(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentLabelsIds); + AssigneesActions.getCurrentIssueAssignees(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentAssignees); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { + viewBinding.scrollViewComments.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { - if((scrollY - oldScrollY) > 0 && createNewComment.isShown()) { - createNewComment.setVisibility(View.GONE); + if((scrollY - oldScrollY) > 0 && viewBinding.addNewComment.isShown()) { + viewBinding.addNewComment.setVisibility(View.GONE); } else if((scrollY - oldScrollY) < 0) { - createNewComment.setVisibility(View.VISIBLE); + viewBinding.addNewComment.setVisibility(View.VISIBLE); } - if(!scrollViewComments.canScrollVertically(1)) { // bottom - createNewComment.setVisibility(View.GONE); + if(!viewBinding.scrollViewComments.canScrollVertically(1)) { // bottom + viewBinding.addNewComment.setVisibility(View.GONE); } - if(!scrollViewComments.canScrollVertically(-1)) { // top - createNewComment.setVisibility(View.VISIBLE); + if(!viewBinding.scrollViewComments.canScrollVertically(-1)) { // top + viewBinding.addNewComment.setVisibility(View.VISIBLE); } }); } - swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { + viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { - swipeRefresh.setRefreshing(false); + viewBinding.pullToRefresh.setRefreshing(false); IssueCommentsViewModel .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, ctx); @@ -215,14 +219,231 @@ public class IssueDetailActivity extends BaseActivity { } - toolbarTitle.setTypeface(myTypeface); - toolbarTitle.setText(repoName); + viewBinding.toolbarTitle.setTypeface(myTypeface); + viewBinding.toolbarTitle.setText(repoName); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); fetchDataAsync(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); } + @Override + public void onButtonClicked(String text) { + + switch(text) { + + case "showLabels": + showLabels(); + break; + + case "showAssignees": + showAssignees(); + break; + } + + } + + @Override + public void labelsInterface(List data) { + } + + @Override + public void labelsIdsInterface(List data) { + + labelsIds = data; + } + + @Override + public void assigneesInterface(List data) { + + assigneesListData = data; + } + + private void showAssignees() { + + assigneesAdapter.updateList(currentAssignees); + dialogAssignees = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); + dialogAssignees.setCancelable(false); + + if (dialogAssignees.getWindow() != null) { + + dialogAssignees.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + } + + assigneesBinding = CustomAssigneesSelectionDialogBinding.inflate(LayoutInflater.from(ctx)); + + View view = assigneesBinding.getRoot(); + dialogAssignees.setContentView(view); + + assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> { + + currentAssignees = new ArrayList<>(new LinkedHashSet<>(currentAssignees)); + assigneesListData = new ArrayList<>(new LinkedHashSet<>(assigneesListData)); + Collections.sort(assigneesListData); + Collections.sort(currentAssignees); + + if(!assigneesListData.equals(currentAssignees)) { + + updateIssueAssignees(); + } + else { + + dialogAssignees.dismiss(); + } + }); + + AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); + } + + public void showLabels() { + + labelsAdapter.updateList(currentLabelsIds); + dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); + dialogLabels.setCancelable(false); + + 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(labelsBinding_ -> { + + currentLabelsIds = new ArrayList<>(new LinkedHashSet<>(currentLabelsIds)); + labelsIds = new ArrayList<>(new LinkedHashSet<>(labelsIds)); + Collections.sort(labelsIds); + Collections.sort(currentLabelsIds); + + if(!labelsIds.equals(currentLabelsIds)) { + + updateIssueLabels(); + } + else { + + dialogLabels.dismiss(); + } + }); + + LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); + } + + private void updateIssueAssignees() { + + UpdateIssueAssignees updateAssigneeJson = new UpdateIssueAssignees(assigneesListData); + + Call call3; + + call3 = RetrofitClient + .getInstance(instanceUrl, ctx) + .getApiInterface() + .patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson); + + call3.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response2) { + + if(response2.code() == 201) { + + Toasty.success(ctx, ctx.getString(R.string.assigneesUpdated)); + + dialogAssignees.dismiss(); + + viewBinding.frameAssignees.removeAllViews(); + viewBinding.frameLabels.removeAllViews(); + getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); + currentAssignees.clear(); + new Handler(Looper.getMainLooper()).postDelayed(() -> AssigneesActions.getCurrentIssueAssignees(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentAssignees), 1000); + } + else if(response2.code() == 401) { + + 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(response2.code() == 403) { + + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + } + else if(response2.code() == 404) { + + Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); + } + else { + + Toasty.error(ctx, getString(R.string.genericError)); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); + } + }); + + } + + private void updateIssueLabels() { + + Labels patchIssueLabels = new Labels(labelsIds); + + Call call = RetrofitClient + .getInstance(instanceUrl, ctx) + .getApiInterface() + .updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + if(response.code() == 200) { + + Toasty.success(ctx, ctx.getString(R.string.labelsUpdated)); + dialogLabels.dismiss(); + + viewBinding.frameAssignees.removeAllViews(); + viewBinding.frameLabels.removeAllViews(); + getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); + currentLabelsIds.clear(); + new Handler(Looper.getMainLooper()).postDelayed(() -> LabelsActions.getCurrentIssueLabels(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentLabelsIds), 1000); + } + else if(response.code() == 401) { + + 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() == 403) { + + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + } + else if(response.code() == 404) { + + Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); + } + else { + + Toasty.error(ctx, getString(R.string.genericError)); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); + } + }); + + } + @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -254,24 +475,15 @@ public class IssueDetailActivity extends BaseActivity { public void onResume() { super.onResume(); - final TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); if(tinyDb.getBoolean("commentPosted")) { - scrollViewComments.post(() -> { + viewBinding.scrollViewComments.post(() -> { IssueCommentsViewModel .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, ctx); - new Handler().postDelayed(() -> scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000); + new Handler(Looper.getMainLooper()).postDelayed(() -> viewBinding.scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000); tinyDb.putBoolean("commentPosted", false); @@ -279,7 +491,7 @@ public class IssueDetailActivity extends BaseActivity { } if(tinyDb.getBoolean("commentEdited")) { - scrollViewComments.post(() -> { + viewBinding.scrollViewComments.post(() -> { IssueCommentsViewModel .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, @@ -291,10 +503,10 @@ public class IssueDetailActivity extends BaseActivity { if(tinyDb.getBoolean("singleIssueUpdate")) { - new Handler().postDelayed(() -> { + new Handler(Looper.getMainLooper()).postDelayed(() -> { - assigneesLayout.removeAllViews(); - labelsLayout.removeAllViews(); + viewBinding.frameAssignees.removeAllViews(); + viewBinding.frameLabels.removeAllViews(); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); tinyDb.putBoolean("singleIssueUpdate", false); @@ -304,10 +516,10 @@ public class IssueDetailActivity extends BaseActivity { if(tinyDb.getBoolean("issueEdited")) { - new Handler().postDelayed(() -> { + new Handler(Looper.getMainLooper()).postDelayed(() -> { - assigneesLayout.removeAllViews(); - labelsLayout.removeAllViews(); + viewBinding.frameAssignees.removeAllViews(); + viewBinding.frameLabels.removeAllViews(); getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); tinyDb.putBoolean("issueEdited", false); @@ -327,11 +539,11 @@ public class IssueDetailActivity extends BaseActivity { assert issueCommentsMain != null; if(issueCommentsMain.size() > 0) { - divider.setVisibility(View.VISIBLE); + viewBinding.divider.setVisibility(View.VISIBLE); } adapter = new IssueCommentsAdapter(ctx, issueCommentsMain); - mRecyclerView.setAdapter(adapter); + viewBinding.recyclerView.setAdapter(adapter); }); @@ -353,25 +565,25 @@ public class IssueDetailActivity extends BaseActivity { Issues singleIssue = response.body(); assert singleIssue != null; - issuePrState.setVisibility(View.VISIBLE); + viewBinding.issuePrState.setVisibility(View.VISIBLE); if(singleIssue.getPull_request() != null) { if(singleIssue.getPull_request().isMerged()) { // merged - issuePrState.setImageResource(R.drawable.ic_pull_request_merged); + viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request_merged); } else if(!singleIssue.getPull_request().isMerged() && singleIssue.getState().equals("closed")) { // closed - issuePrState.setImageResource(R.drawable.ic_pull_request_closed); + viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request_closed); } else { // open - issuePrState.setImageResource(R.drawable.ic_pull_request); + viewBinding.issuePrState.setImageResource(R.drawable.ic_pull_request); } } else if(singleIssue.getState().equals("closed")) { // issue closed - issuePrState.setImageResource(R.drawable.ic_issue_closed_red); + viewBinding.issuePrState.setImageResource(R.drawable.ic_issue_closed_red); } final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create()) @@ -424,21 +636,21 @@ public class IssueDetailActivity extends BaseActivity { tinyDb.putString("singleIssueHtmlUrl", singleIssue.getHtml_url()); PicassoService.getInstance(ctx).get().load(singleIssue.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated) - .transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); + .transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(viewBinding.assigneeAvatar); String issueNumber_ = "" + appCtx.getResources() .getString(R.string.hash) + singleIssue.getNumber() + ""; - issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); + viewBinding.issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); String cleanIssueDescription = singleIssue.getBody().trim(); Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); - markwon.setParsedMarkdown(issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription)); + markwon.setParsedMarkdown(viewBinding.issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription)); - RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) issueDescription.getLayoutParams(); + RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) viewBinding.issueDescription.getLayoutParams(); LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80); params1.setMargins(15, 0, 0, 0); if(singleIssue.getAssignees() != null) { - assigneesScrollView.setVisibility(View.VISIBLE); + viewBinding.assigneesScrollView.setVisibility(View.VISIBLE); for(int i = 0; i < singleIssue.getAssignees().size(); i++) { ImageView assigneesView = new ImageView(ctx); @@ -447,7 +659,7 @@ public class IssueDetailActivity extends BaseActivity { .placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(100, 100).centerCrop() .into(assigneesView); - assigneesLayout.addView(assigneesView); + viewBinding.frameAssignees.addView(assigneesView); assigneesView.setLayoutParams(params1); if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) { assigneesView.setOnClickListener( @@ -461,7 +673,7 @@ public class IssueDetailActivity extends BaseActivity { } } else { - assigneesScrollView.setVisibility(View.GONE); + viewBinding.assigneesScrollView.setVisibility(View.GONE); } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, @@ -469,7 +681,7 @@ public class IssueDetailActivity extends BaseActivity { params.setMargins(0, 0, 15, 0); if(singleIssue.getLabels() != null) { - labelsScrollView.setVisibility(View.VISIBLE); + viewBinding.labelsScrollView.setVisibility(View.VISIBLE); for(int i = 0; i < singleIssue.getLabels().size(); i++) { @@ -478,8 +690,8 @@ public class IssueDetailActivity extends BaseActivity { int color = Color.parseColor("#" + labelColor); ImageView labelsView = new ImageView(ctx); - labelsLayout.setOrientation(LinearLayout.HORIZONTAL); - labelsLayout.setGravity(Gravity.START | Gravity.TOP); + viewBinding.frameLabels.setOrientation(LinearLayout.HORIZONTAL); + viewBinding.frameLabels.setGravity(Gravity.START | Gravity.TOP); labelsView.setLayoutParams(params); int height = AppUtil.getPixelsFromDensity(ctx, 25); @@ -491,12 +703,12 @@ public class IssueDetailActivity extends BaseActivity { .height(height).endConfig().buildRoundRect(labelName, color, AppUtil.getPixelsFromDensity(ctx, 5)); labelsView.setImageDrawable(drawable); - labelsLayout.addView(labelsView); + viewBinding.frameLabels.addView(labelsView); } } else { - labelsScrollView.setVisibility(View.GONE); + viewBinding.labelsScrollView.setVisibility(View.GONE); } if(singleIssue.getDue_date() != null) { @@ -504,77 +716,77 @@ public class IssueDetailActivity extends BaseActivity { if(timeFormat.equals("normal") || timeFormat.equals("pretty")) { DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); String dueDate = formatter.format(singleIssue.getDue_date()); - issueDueDate.setText(dueDate); - issueDueDate + viewBinding.issueDueDate.setText(dueDate); + viewBinding.issueDueDate .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), ctx)); } else if(timeFormat.equals("normal1")) { DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); String dueDate = formatter.format(singleIssue.getDue_date()); - issueDueDate.setText(dueDate); + viewBinding.issueDueDate.setText(dueDate); } } else { - issueDueDate.setVisibility(View.GONE); + viewBinding.issueDueDate.setVisibility(View.GONE); } String edited; if(!singleIssue.getUpdated_at().equals(singleIssue.getCreated_at())) { edited = getString(R.string.colorfulBulletSpan) + getString(R.string.modifiedText); - issueModified.setVisibility(View.VISIBLE); - issueModified.setText(edited); - issueModified + viewBinding.issueModified.setVisibility(View.VISIBLE); + viewBinding.issueModified.setText(edited); + viewBinding.issueModified .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getUpdated_at()), ctx)); } else { - issueModified.setVisibility(View.INVISIBLE); + viewBinding.issueModified.setVisibility(View.INVISIBLE); } if((singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) && singleIssue.getAssignees() != null) { paramsDesc.setMargins(0, 35, 0, 0); - issueDescription.setLayoutParams(paramsDesc); + viewBinding.issueDescription.setLayoutParams(paramsDesc); } else if(singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) { paramsDesc.setMargins(0, 55, 0, 0); - issueDescription.setLayoutParams(paramsDesc); + viewBinding.issueDescription.setLayoutParams(paramsDesc); } else if(singleIssue.getAssignees() == null) { paramsDesc.setMargins(0, 35, 0, 0); - issueDescription.setLayoutParams(paramsDesc); + viewBinding.issueDescription.setLayoutParams(paramsDesc); } else { paramsDesc.setMargins(0, 15, 0, 0); - issueDescription.setLayoutParams(paramsDesc); + viewBinding.issueDescription.setLayoutParams(paramsDesc); } - issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx)); - issueCreatedTime.setVisibility(View.VISIBLE); + viewBinding.issueCreatedTime.setText(TimeHelper.formatTime(singleIssue.getCreated_at(), new Locale(locale), timeFormat, ctx)); + viewBinding.issueCreatedTime.setVisibility(View.VISIBLE); if(timeFormat.equals("pretty")) { - issueCreatedTime + viewBinding.issueCreatedTime .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), ctx)); } if(singleIssue.getMilestone() != null) { - issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle())); + viewBinding.issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle())); } else { - issueMilestone.setVisibility(View.GONE); + viewBinding.issueMilestone.setVisibility(View.GONE); } if(!singleIssue.getUser().getFull_name().equals("")) { - assigneeAvatar.setOnClickListener( + viewBinding.assigneeAvatar.setOnClickListener( new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx)); } else { - assigneeAvatar.setOnClickListener( + viewBinding.assigneeAvatar.setOnClickListener( new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx)); } - progressBar.setVisibility(View.GONE); + viewBinding.progressBar.setVisibility(View.GONE); } diff --git a/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java b/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java index cac8891c..e7016da7 100644 --- a/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java @@ -4,19 +4,16 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; -import android.view.Gravity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; -import android.widget.ImageView; import android.widget.RadioGroup; import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import com.tooltip.Tooltip; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.database.api.UserAccountsApi; @@ -82,7 +79,6 @@ public class LoginActivity extends BaseActivity { loginPassword = findViewById(R.id.login_passwd); otpCode = findViewById(R.id.otpCode); otpInfo = findViewById(R.id.otpInfo); - ImageView info_button = findViewById(R.id.info); protocolSpinner = findViewById(R.id.httpsSpinner); loginMethod = findViewById(R.id.loginMethod); loginTokenCode = findViewById(R.id.loginTokenCode); @@ -108,11 +104,6 @@ public class LoginActivity extends BaseActivity { }); - info_button.setOnClickListener( - view -> new Tooltip.Builder(view).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.colorWhite)) - .setBackgroundColor(getResources().getColor(R.color.tooltipBackground)).setCancelable(true).setDismissOnClick(true).setPadding(30) - .setCornerRadius(R.dimen.tooltipCornor).setGravity(Gravity.BOTTOM).show()); - loginMethod.setOnCheckedChangeListener((group, checkedId) -> { if(checkedId == R.id.loginToken) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java new file mode 100644 index 00000000..d80fa661 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java @@ -0,0 +1,130 @@ +package org.mian.gitnex.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import org.mian.gitnex.R; +import org.mian.gitnex.clients.PicassoService; +import org.mian.gitnex.helpers.RoundedTransformation; +import org.mian.gitnex.models.Collaborators; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; + +/** + * Author M M Arif + */ + +public class AssigneesListAdapter extends RecyclerView.Adapter { + + private Context mCtx; + private List assigneesList; + private List assigneesStrings = new ArrayList<>(); + private List currentAssignees; + + private AssigneesListAdapterListener assigneesListener; + + public interface AssigneesListAdapterListener { + + void assigneesInterface(List data); + } + + public AssigneesListAdapter(Context mCtx, List dataMain, AssigneesListAdapterListener assigneesListener, List currentAssignees) { + + this.mCtx = mCtx; + this.assigneesList = dataMain; + this.assigneesListener = assigneesListener; + this.currentAssignees = currentAssignees; + } + + static class AssigneesViewHolder extends RecyclerView.ViewHolder { + + private CheckBox assigneesSelection; + private TextView assigneesName; + private ImageView assigneesAvatar; + + private AssigneesViewHolder(View itemView) { + super(itemView); + + assigneesSelection = itemView.findViewById(R.id.assigneesSelection); + assigneesName = itemView.findViewById(R.id.assigneesName); + assigneesAvatar = itemView.findViewById(R.id.assigneesAvatar); + + } + } + + @NonNull + @Override + public AssigneesListAdapter.AssigneesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_assignees_list, parent, false); + return new AssigneesListAdapter.AssigneesViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull AssigneesListAdapter.AssigneesViewHolder holder, int position) { + + Collaborators currentItem = assigneesList.get(position); + + if(currentItem.getFull_name().equals("")) { + holder.assigneesName.setText(currentItem.getLogin()); + } + else { + holder.assigneesName.setText(currentItem.getFull_name()); + } + PicassoService + .getInstance(mCtx).get().load(currentItem.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(holder.assigneesAvatar); + + for(int i = 0; i < assigneesList.size(); i++) { + + if(assigneesStrings.contains(currentItem.getLogin())) { + + holder.assigneesSelection.setChecked(true); + } + } + + currentAssignees = new ArrayList<>(new LinkedHashSet<>(currentAssignees)); + for(int i = 0; i < currentAssignees.size(); i++) { + + if(currentAssignees.contains(currentItem.getLogin())) { + + holder.assigneesSelection.setChecked(true); + assigneesStrings.add(currentAssignees.get(i)); + } + } + assigneesListener.assigneesInterface(assigneesStrings); + + holder.assigneesSelection.setOnCheckedChangeListener((buttonView, isChecked) -> { + + if(isChecked) { + + assigneesStrings.add(currentItem.getLogin()); + } + else { + + assigneesStrings.remove(currentItem.getLogin()); + } + + assigneesListener.assigneesInterface(assigneesStrings); + }); + + assigneesStrings = new ArrayList<>(new LinkedHashSet<>(assigneesStrings)); + } + + @Override + public int getItemCount() { + return assigneesList.size(); + } + + public void updateList(List list) { + + currentAssignees = list; + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java index 92b8ba54..be152b12 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java @@ -1,14 +1,18 @@ package org.mian.gitnex.adapters; +import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.TextView; 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.LinkedHashSet; import java.util.List; /** @@ -17,32 +21,38 @@ import java.util.List; public class LabelsListAdapter extends RecyclerView.Adapter { + private List currentLabelsIds; private List labels; - private ArrayList labelsStrings = new ArrayList<>(); - private ArrayList labelsIds = new ArrayList<>(); + private List labelsStrings = new ArrayList<>(); + private List labelsIds = new ArrayList<>(); private LabelsListAdapterListener labelsListener; public interface LabelsListAdapterListener { - void labelsStringData(ArrayList data); - void labelsIdsData(ArrayList data); + void labelsInterface(List data); + void labelsIdsInterface(List data); } - public LabelsListAdapter(List labelsMain, LabelsListAdapterListener labelsListener) { + public LabelsListAdapter(List labelsMain, LabelsListAdapterListener labelsListener, List currentLabelsIds) { this.labels = labelsMain; this.labelsListener = labelsListener; + this.currentLabelsIds = currentLabelsIds; } static class LabelsViewHolder extends RecyclerView.ViewHolder { private CheckBox labelSelection; + private TextView labelText; + private ImageView labelColor; private LabelsViewHolder(View itemView) { super(itemView); labelSelection = itemView.findViewById(R.id.labelSelection); + labelText = itemView.findViewById(R.id.labelText); + labelColor = itemView.findViewById(R.id.labelColor); } } @@ -60,7 +70,11 @@ public class LabelsListAdapter extends RecyclerView.Adapter(new LinkedHashSet<>(currentLabelsIds)); + for(int i = 0; i < currentLabelsIds.size(); i++) { + + if(currentLabelsIds.contains(currentItem.getId())) { + + holder.labelSelection.setChecked(true); + labelsIds.add(currentLabelsIds.get(i)); + } + } + labelsListener.labelsIdsInterface(labelsIds); + holder.labelSelection.setOnCheckedChangeListener((buttonView, isChecked) -> { if(isChecked) { @@ -83,13 +108,21 @@ public class LabelsListAdapter extends RecyclerView.Adapter(new LinkedHashSet<>(labelsIds)); } @Override public int getItemCount() { return labels.size(); } + + public void updateList(List list) { + + currentLabelsIds = list; + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/MutliSelectAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MutliSelectAdapter.java deleted file mode 100644 index 3f4d41a3..00000000 --- a/app/src/main/java/org/mian/gitnex/adapters/MutliSelectAdapter.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.mian.gitnex.adapters; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Typeface; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.TextAppearanceSpan; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatCheckBox; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; -import org.mian.gitnex.R; -import org.mian.gitnex.helpers.MultiSelectDialog; -import org.mian.gitnex.models.MultiSelectModel; -import java.util.List; - -/** - * Author com.github.abumoallim, modified by M M Arif - */ - -public class MutliSelectAdapter extends RecyclerView.Adapter { - - private List mDataSet; - private String mSearchQuery = ""; - private Context mContext; - - public MutliSelectAdapter(List dataSet, Context context) { - this.mDataSet = dataSet; - this.mContext = context; - } - - @NonNull - @Override - public MultiSelectDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_select_item, parent, false); - return new MultiSelectDialogViewHolder(view); - - } - - @Override - public void onBindViewHolder(@NonNull final MultiSelectDialogViewHolder holder, int position) { - - if (!mSearchQuery.equals("") && mSearchQuery.length() > 1) { - setHighlightedText(position, holder.dialog_name_item); - } else { - holder.dialog_name_item.setText(mDataSet.get(position).getName()); - } - - if (mDataSet.get(position).getSelected()) { - - if (!MultiSelectDialog.selectedIdsForCallback.contains(mDataSet.get(position).getId())) { - MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(position).getId()); - } - } - - if (checkForSelection(mDataSet.get(position).getId())) { - holder.dialog_item_checkbox.setChecked(true); - } else { - holder.dialog_item_checkbox.setChecked(false); - } - - /*holder.dialog_item_checkbox.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (holder.dialog_item_checkbox.isChecked()) { - MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId()); - holder.dialog_item_checkbox.setChecked(true); - } else { - removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId()); - holder.dialog_item_checkbox.setChecked(false); - } - } - });*/ - - holder.main_container.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View view) { - if (!holder.dialog_item_checkbox.isChecked()) { - MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId()); - holder.dialog_item_checkbox.setChecked(true); - mDataSet.get(holder.getAdapterPosition()).setSelected(true); - notifyItemChanged(holder.getAdapterPosition()); - } else { - removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId()); - holder.dialog_item_checkbox.setChecked(false); - mDataSet.get(holder.getAdapterPosition()).setSelected(false); - notifyItemChanged(holder.getAdapterPosition()); - } - } - - }); - } - - private void setHighlightedText(int position, TextView textview) { - - String name = mDataSet.get(position).getName(); - SpannableString str = new SpannableString(name); - int endLength = name.toLowerCase().indexOf(mSearchQuery) + mSearchQuery.length(); - ColorStateList highlightedColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{ContextCompat.getColor(mContext, R.color.colorAccent)}); - TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(null, Typeface.NORMAL, -1, highlightedColor, null); - str.setSpan(textAppearanceSpan, name.toLowerCase().indexOf(mSearchQuery), endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - textview.setText(str); - - } - - private void removeFromSelection(Integer id) { - - for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) { - if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) { - MultiSelectDialog.selectedIdsForCallback.remove(i); - } - } - - } - - private boolean checkForSelection(Integer id) { - - for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) { - if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) { - return true; - } - } - return false; - - } - - /*//get selected name string separated by coma - public String getDataString() { - String data = ""; - for (int i = 0; i < mDataSet.size(); i++) { - if (checkForSelection(mDataSet.get(i).getId())) { - data = data + ", " + mDataSet.get(i).getName(); - } - } - if (data.length() > 0) { - return data.substring(1); - } else { - return ""; - } - } - //get selected name ararylist - public ArrayList getSelectedNameList() { - ArrayList names = new ArrayList<>(); - for (int i = 0; i < mDataSet.size(); i++) { - if (checkForSelection(mDataSet.get(i).getId())) { - names.add(mDataSet.get(i).getName()); - } - } - // return names.toArray(new String[names.size()]); - return names; - }*/ - - @Override - public int getItemCount() { - return mDataSet.size(); - } - - public void setData(List data, String query, MutliSelectAdapter mutliSelectAdapter) { - - this.mDataSet = data; - this.mSearchQuery = query; - mutliSelectAdapter.notifyDataSetChanged(); - - } - - class MultiSelectDialogViewHolder extends RecyclerView.ViewHolder { - - private TextView dialog_name_item; - private AppCompatCheckBox dialog_item_checkbox; - private LinearLayout main_container; - - MultiSelectDialogViewHolder(View view) { - - super(view); - dialog_name_item = view.findViewById(R.id.dialog_item_name); - dialog_item_checkbox = view.findViewById(R.id.dialog_item_checkbox); - main_container = view.findViewById(R.id.main_container); - - } - - } -} diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java index a38af86f..bd936948 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java @@ -14,8 +14,6 @@ import androidx.annotation.Nullable; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.mian.gitnex.R; import org.mian.gitnex.actions.IssueActions; -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; @@ -30,6 +28,8 @@ import java.util.Objects; public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { + private BottomSheetListener bmListener; + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -78,42 +78,36 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { else { mergePullRequest.setVisibility(View.GONE); - } mergePullRequest.setOnClickListener(v13 -> { startActivity(new Intent(ctx, MergePullRequestActivity.class)); dismiss(); - }); openFilesDiff.setOnClickListener(v14 -> { startActivity(new Intent(ctx, FileDiffActivity.class)); dismiss(); - }); editIssue.setOnClickListener(v15 -> { startActivity(new Intent(ctx, EditIssueActivity.class)); dismiss(); - }); editLabels.setOnClickListener(v16 -> { - startActivity(new Intent(ctx, AddRemoveLabelsActivity.class)); + bmListener.onButtonClicked("showLabels"); dismiss(); - }); addRemoveAssignees.setOnClickListener(v17 -> { - startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class)); + bmListener.onButtonClicked("showAssignees"); dismiss(); - }); shareIssue.setOnClickListener(v1 -> { @@ -125,7 +119,6 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"))); dismiss(); - }); copyIssueUrl.setOnClickListener(v12 -> { @@ -139,7 +132,6 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); dismiss(); - }); if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) { @@ -183,14 +175,12 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { IssueActions.subscribe(ctx); dismiss(); - }); unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> { IssueActions.unsubscribe(ctx); dismiss(); - }); if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) { @@ -209,4 +199,23 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { return v; } + public interface BottomSheetListener { + + void onButtonClicked(String text); + } + + @Override + public void onAttach(@NonNull Context context) { + + super.onAttach(context); + + try { + + bmListener = (BottomSheetListener) context; + } + catch(ClassCastException e) { + + throw new ClassCastException(context.toString() + " must implement BottomSheetListener"); + } + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java b/app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java deleted file mode 100644 index 882205f9..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java +++ /dev/null @@ -1,318 +0,0 @@ -package org.mian.gitnex.helpers; - -import android.annotation.SuppressLint; -import android.app.Dialog; -import android.os.Bundle; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.widget.TextView; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatDialogFragment; -import androidx.appcompat.widget.SearchView; -import androidx.recyclerview.widget.LinearLayoutManager; -import org.mian.gitnex.R; -import org.mian.gitnex.adapters.MutliSelectAdapter; -import org.mian.gitnex.models.MultiSelectModel; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Author com.github.abumoallim, modified by M M Arif - */ - -public class MultiSelectDialog extends AppCompatDialogFragment implements SearchView.OnQueryTextListener, View.OnClickListener { - - public static List selectedIdsForCallback = new ArrayList<>(); - - public List mainListOfAdapter = new ArrayList<>(); - private MutliSelectAdapter mutliSelectAdapter; - //Default Values - private String title; - private float titleSize = 25; - private String positiveText = "DONE"; - private String negativeText = "CANCEL"; - private TextView dialogTitle, dialogSubmit, dialogCancel; - private List previouslySelectedIdsList = new ArrayList<>(); - - private List tempPreviouslySelectedIdsList = new ArrayList<>(); - private List tempMainListOfAdapter = new ArrayList<>(); - - private SubmitCallbackListener submitCallbackListener; - - private int minSelectionLimit = 1; - private String minSelectionMessage = null; - private int maxSelectionLimit = 0; - private String maxSelectionMessage = null; - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - - final Dialog dialog = new Dialog(Objects.requireNonNull(getActivity())); - Objects.requireNonNull(dialog.getWindow()).requestFeature(Window.FEATURE_NO_TITLE); - dialog.getWindow().setFlags( - WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - - dialog.setContentView(R.layout.custom_multi_select); - dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - - RecyclerViewEmptySupport mrecyclerView = dialog.findViewById(R.id.recycler_view); - SearchView searchView = dialog.findViewById(R.id.search_view); - dialogTitle = dialog.findViewById(R.id.title); - dialogSubmit = dialog.findViewById(R.id.done); - dialogCancel = dialog.findViewById(R.id.cancel); - - mrecyclerView.setEmptyView(dialog.findViewById(R.id.list_empty1)); - @SuppressLint("WrongConstant") LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); - mrecyclerView.setLayoutManager(layoutManager); - - dialogSubmit.setOnClickListener(this); - dialogCancel.setOnClickListener(this); - - settingValues(); - - mainListOfAdapter = setCheckedIDS(mainListOfAdapter, previouslySelectedIdsList); - mutliSelectAdapter = new MutliSelectAdapter(mainListOfAdapter, getContext()); - mrecyclerView.setAdapter(mutliSelectAdapter); - - searchView.setOnQueryTextListener(this); - searchView.onActionViewExpanded(); - searchView.clearFocus(); - - - return dialog; - } - - public MultiSelectDialog title(String title) { - this.title = title; - return this; - } - - public MultiSelectDialog titleSize(float titleSize) { - this.titleSize = titleSize; - return this; - } - - public MultiSelectDialog positiveText(@NonNull String message) { - this.positiveText = message; - return this; - } - - public MultiSelectDialog negativeText(@NonNull String message) { - this.negativeText = message; - return this; - } - - public MultiSelectDialog preSelectIDsList(List list) { - this.previouslySelectedIdsList = list; - this.tempPreviouslySelectedIdsList = new ArrayList<>(previouslySelectedIdsList); - return this; - } - - public MultiSelectDialog multiSelectList(List list) { - this.mainListOfAdapter = list; - this.tempMainListOfAdapter = new ArrayList<>(mainListOfAdapter); - if(maxSelectionLimit == 0) - maxSelectionLimit = list.size(); - return this; - } - - public MultiSelectDialog setMaxSelectionLimit(int limit){ - this.maxSelectionLimit = limit; - return this; - } - - public MultiSelectDialog setMaxSelectionMessage(String message) { - this.maxSelectionMessage = message; - return this; - } - - public MultiSelectDialog setMinSelectionLimit(int limit){ - this.minSelectionLimit = limit; - return this; - } - - public MultiSelectDialog setMinSelectionMessage(String message) { - this.minSelectionMessage = message; - return this; - } - - public MultiSelectDialog onSubmit(@NonNull SubmitCallbackListener callback) { - this.submitCallbackListener = callback; - return this; - } - - private void settingValues() { - dialogTitle.setText(title); - dialogTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, titleSize); - dialogSubmit.setText(positiveText.toUpperCase()); - dialogCancel.setText(negativeText.toUpperCase()); - } - - private List setCheckedIDS(List multiselectdata, List listOfIdsSelected) { - - for (int i = 0; i < multiselectdata.size(); i++) { - multiselectdata.get(i).setSelected(false); - for (int j = 0; j < listOfIdsSelected.size(); j++) { - if (listOfIdsSelected.get(j) == (multiselectdata.get(i).getId())) { - multiselectdata.get(i).setSelected(true); - } - } - } - return multiselectdata; - - } - - private List filter(List models, String query) { - - query = query.toLowerCase(); - final List filteredModelList = new ArrayList<>(); - if (query.equals("") | query.isEmpty()) { - filteredModelList.addAll(models); - return filteredModelList; - } - - for (MultiSelectModel model : models) { - final String name = model.getName().toLowerCase(); - if (name.contains(query)) { - filteredModelList.add(model); - } - } - return filteredModelList; - - } - - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - - selectedIdsForCallback = previouslySelectedIdsList; - mainListOfAdapter = setCheckedIDS(mainListOfAdapter, selectedIdsForCallback); - List filteredlist = filter(mainListOfAdapter, newText); - mutliSelectAdapter.setData(filteredlist, newText.toLowerCase(), mutliSelectAdapter); - return false; - - } - - @Override - public void onClick(View view) { - - if (view.getId() == R.id.done) { - List callBackListOfIds = selectedIdsForCallback; - - if (callBackListOfIds.size() >= minSelectionLimit) { - if (callBackListOfIds.size() <= maxSelectionLimit) { - - //to remember last selected ids which were successfully done - tempPreviouslySelectedIdsList = new ArrayList<>(callBackListOfIds); - - if(submitCallbackListener !=null) { - submitCallbackListener.onSelected(callBackListOfIds, getSelectNameList(), getSelectedDataString()); - } - dismiss(); - } else { - String youCan = getResources().getString(R.string.you_can_only_select_upto); - String options = getResources().getString(R.string.options); - String option = getResources().getString(R.string.option); - String message = ""; - - if(this.maxSelectionMessage != null) { - message = maxSelectionMessage; - } - else { - if (maxSelectionLimit > 1) - message = youCan + " " + maxSelectionLimit + " " + options; - else - message = youCan + " " + maxSelectionLimit + " " + option; - } - Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show(); - } - } else { - String pleaseSelect = getResources().getString(R.string.please_select_atleast); - String options = getResources().getString(R.string.options); - String option = getResources().getString(R.string.option); - String message = ""; - - if(this.minSelectionMessage != null) { - message = minSelectionMessage; - } - else { - if (minSelectionLimit > 1) - message = pleaseSelect + " " + minSelectionLimit + " " + options; - else - message = pleaseSelect + " " + minSelectionLimit + " " + option; - } - Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show(); - } - } - - if (view.getId() == R.id.cancel) { - if(submitCallbackListener!=null){ - selectedIdsForCallback.clear(); - selectedIdsForCallback.addAll(tempPreviouslySelectedIdsList); - submitCallbackListener.onCancel(); - } - dismiss(); - } - - } - - private String getSelectedDataString() { - - String data = ""; - for (int i = 0; i < tempMainListOfAdapter.size(); i++) { - if (checkForSelection(tempMainListOfAdapter.get(i).getId())) { - data = data + ", " + tempMainListOfAdapter.get(i).getName(); - } - } - if (data.length() > 0) { - return data.substring(1); - } else { - return ""; - } - - } - - private List getSelectNameList() { - - List names = new ArrayList<>(); - for(int i=0;i selectedIds, List selectedNames, String commonSeperatedData); - void onCancel(); - } - -} 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 dcf3ab38..df0f2fd4 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -163,6 +163,9 @@ public interface ApiInterface { @GET("repos/{owner}/{repo}/collaborators") // get collaborators list Call> getCollaborators(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); + @GET("orgs/{org}/members") // get organization members + Call> getOrgMembers(@Header("Authorization") String token, @Path("org") String ownerName); + @POST("repos/{owner}/{repo}/milestones") // create new milestone Call createMilestone(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body Milestones jsonStr); diff --git a/app/src/main/java/org/mian/gitnex/models/Collaborators.java b/app/src/main/java/org/mian/gitnex/models/Collaborators.java index b82fd171..2edd579f 100644 --- a/app/src/main/java/org/mian/gitnex/models/Collaborators.java +++ b/app/src/main/java/org/mian/gitnex/models/Collaborators.java @@ -1,5 +1,7 @@ package org.mian.gitnex.models; +import java.util.Objects; + /** * Author M M Arif */ @@ -14,6 +16,13 @@ public class Collaborators { private String language; private String username; + public Collaborators(String full_name, String login, String avatar_url) { + + this.full_name = full_name; + this.login = login; + this.avatar_url = avatar_url; + } + public int getId() { return id; } @@ -41,4 +50,24 @@ public class Collaborators { public String getUsername() { return username; } + + @Override + public boolean equals(Object o) { + + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + Collaborators that = (Collaborators) o; + return Objects.equals(login, that.login); + } + + @Override + public int hashCode() { + + return Objects.hash(login); + } + } diff --git a/app/src/main/java/org/mian/gitnex/models/CreateIssue.java b/app/src/main/java/org/mian/gitnex/models/CreateIssue.java index e15252b9..974cb513 100644 --- a/app/src/main/java/org/mian/gitnex/models/CreateIssue.java +++ b/app/src/main/java/org/mian/gitnex/models/CreateIssue.java @@ -15,9 +15,9 @@ public class CreateIssue { private String title; private List assignees; - private int[] labels; + private List labels; - public CreateIssue(String assignee, String body, boolean closed, String due_date, int milestone, String title, List assignees, int[] labels) { + public CreateIssue(String assignee, String body, boolean closed, String due_date, int milestone, String title, List assignees, List labels) { this.body = body; this.closed = closed; this.due_date = due_date; diff --git a/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java b/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java index 91c4b074..4d4a1e9f 100644 --- a/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java +++ b/app/src/main/java/org/mian/gitnex/models/CreatePullRequest.java @@ -1,6 +1,6 @@ package org.mian.gitnex.models; -import java.util.ArrayList; +import java.util.List; /** * Author M M Arif @@ -17,10 +17,10 @@ public class CreatePullRequest { private String due_date; private String message; - private ArrayList assignees; - private ArrayList labels; + private List assignees; + private List labels; - public CreatePullRequest(String title, String body, String assignee, String base, String head, int milestone, String due_date, ArrayList assignees, ArrayList labels) { + public CreatePullRequest(String title, String body, String assignee, String base, String head, int milestone, String due_date, List assignees, List labels) { this.title = title; this.body = body; 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 87ca1aaa..90630930 100644 --- a/app/src/main/java/org/mian/gitnex/models/Labels.java +++ b/app/src/main/java/org/mian/gitnex/models/Labels.java @@ -1,5 +1,7 @@ package org.mian.gitnex.models; +import java.util.List; + /** * Author M M Arif */ @@ -10,20 +12,21 @@ public class Labels { private String name; private String color; private String url; - private int[] labels; + private List labels; public Labels(String name, String color) { this.name = name; this.color = color; } - public Labels(int[] labels) { + public Labels(List labels) { this.labels = labels; } - public Labels(int id, String name) { + public Labels(int id, String name, String color) { this.id = id; this.name = name; + this.color = color; } public int getId() { diff --git a/app/src/main/res/layout/activity_add_remove_assignees.xml b/app/src/main/res/layout/activity_add_remove_assignees.xml deleted file mode 100644 index 5dd2573a..00000000 --- a/app/src/main/res/layout/activity_add_remove_assignees.xml +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/app/src/main/res/layout/activity_add_remove_labels.xml b/app/src/main/res/layout/activity_add_remove_labels.xml deleted file mode 100644 index 2c4cd512..00000000 --- a/app/src/main/res/layout/activity_add_remove_labels.xml +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/app/src/main/res/layout/activity_create_issue.xml b/app/src/main/res/layout/activity_create_issue.xml index e6fb42e5..eee74b7c 100644 --- a/app/src/main/res/layout/activity_create_issue.xml +++ b/app/src/main/res/layout/activity_create_issue.xml @@ -1,7 +1,7 @@ - @@ -55,155 +55,155 @@ android:padding="16dp" android:orientation="vertical"> - - - + app:hintTextColor="?attr/hintColor" + app:boxStrokeErrorColor="@color/darkRed" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + app:endIconMode="clear_text" + app:endIconTint="?attr/iconsColor" + app:counterEnabled="true" + app:counterMaxLength="255" + app:counterTextColor="?attr/inputTextColor" + android:hint="@string/newIssueTitle"> - - - - - - - - - - - - - - - + android:textColor="?attr/inputTextColor" + android:textColorHighlight="?attr/hintColor" + android:textColorHint="?attr/hintColor" + android:textSize="16sp" /> - + - - - + app:hintTextColor="?attr/hintColor" + app:boxStrokeErrorColor="@color/darkRed" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + app:endIconMode="clear_text" + app:endIconTint="?attr/iconsColor" + android:hint="@string/newIssueDescriptionTitle"> - + + + + - - + app:hintTextColor="?attr/hintColor" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:hint="@string/newIssueAssigneesListTitle"> + + + + + + + + + + + + + + + + + + + + + +