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..ddfa3c9f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,49 +17,79 @@ android:supportsRtl="true" tools:targetApi="n"> - + - - - - + android:name=".activities.AdminGetUsersActivity" + android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> - - - - + android:name=".activities.CreateReleaseActivity" + android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> + + + + + + - - - - + + + + - + @@ -68,24 +98,61 @@ - - - - - - - - - - - - - - - - - + android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" + android:launchMode="singleTask" + android:theme="@android:style/Theme.NoTitleBar"/> + + + + + + + + + + + + + + + + + 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/CommitsActivity.java b/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java index 14c567f8..75b31fae 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java @@ -24,6 +24,7 @@ import org.mian.gitnex.clients.AppApiService; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.models.Commits; @@ -115,7 +116,6 @@ public class CommitsActivity extends BaseActivity { int page = (commitsList.size() + resultLimit) / resultLimit; loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit); - } })); @@ -138,7 +138,7 @@ public class CommitsActivity extends BaseActivity { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { - if(response.isSuccessful()) { + if(response.code() == 200) { assert response.body() != null; if(response.body().size() > 0) { @@ -150,13 +150,15 @@ public class CommitsActivity extends BaseActivity { } else { + commitsList.clear(); adapter.notifyDataChanged(); noData.setVisibility(View.VISIBLE); } + } + if(response.code() == 409) { - progressBar.setVisibility(View.GONE); - + noData.setVisibility(View.VISIBLE); } else { @@ -164,12 +166,13 @@ public class CommitsActivity extends BaseActivity { } + progressBar.setVisibility(View.GONE); } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e(TAG, t.toString()); + Toasty.error(ctx, getResources().getString(R.string.errorOnLogin)); } }); @@ -190,23 +193,19 @@ public class CommitsActivity extends BaseActivity { if(response.isSuccessful()) { List result = response.body(); - assert result != null; + if(result.size() > 0) { pageSize = result.size(); commitsList.addAll(result); - } else { adapter.setMoreDataAvailable(false); - } adapter.notifyDataChanged(); - progressLoadMore.setVisibility(View.GONE); - } else { @@ -214,13 +213,13 @@ public class CommitsActivity extends BaseActivity { } + progressLoadMore.setVisibility(View.GONE); } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e(TAG, t.toString()); - + Toasty.error(ctx, getResources().getString(R.string.errorOnLogin)); } }); 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/fragments/FilesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java index 986187e3..c9e061e0 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java @@ -207,17 +207,19 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, ref, getContext()).observe(getViewLifecycleOwner(), filesListMain -> { + filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); mBreadcrumbsView.removeItemAfter(1); if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame); noDataFiles.setVisibility(View.GONE); } else { + adapter.notifyDataSetChanged(); mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles); @@ -225,7 +227,6 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter filesFrame.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.GONE); - }); } @@ -237,7 +238,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, ref, getContext()).observe(this, filesListMain2 -> { + filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, ref, getContext(), mProgressBar, noDataFiles).observe(this, filesListMain2 -> { adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this); 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/java/org/mian/gitnex/viewmodels/FilesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java index 538757bf..70db17bb 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java @@ -1,7 +1,9 @@ package org.mian.gitnex.viewmodels; import android.content.Context; -import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; @@ -25,15 +27,15 @@ public class FilesViewModel extends ViewModel { private static MutableLiveData> filesList; private static MutableLiveData> filesList2; - public LiveData> getFilesList(String instanceUrl, String token, String owner, String repo, String ref, Context ctx) { + public LiveData> getFilesList(String instanceUrl, String token, String owner, String repo, String ref, Context ctx, ProgressBar progressBar, TextView noDataFiles) { filesList = new MutableLiveData<>(); - loadFilesList(instanceUrl, token, owner, repo, ref, ctx); + loadFilesList(instanceUrl, token, owner, repo, ref, ctx, progressBar, noDataFiles); return filesList; } - private static void loadFilesList(String instanceUrl, String token, String owner, String repo, String ref, final Context ctx) { + private static void loadFilesList(String instanceUrl, String token, String owner, String repo, String ref, final Context ctx, ProgressBar progressBar, TextView noDataFiles) { Call> call = RetrofitClient .getInstance(instanceUrl, ctx) @@ -45,37 +47,47 @@ public class FilesViewModel extends ViewModel { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { - if (response.isSuccessful()) { + if (response.code() == 200) { assert response.body() != null; - Collections.sort(response.body(), (byType1, byType2) -> byType1.getType().compareTo(byType2.getType())); - filesList.postValue(response.body()); - } else { + if(response.body().size() > 0) { - Toasty.warning(ctx, ctx.getString(R.string.noDataFilesTab)); - Log.i("onResponse", String.valueOf(response.code())); + Collections.sort(response.body(), (byType1, byType2) -> byType1.getType().compareTo(byType2.getType())); + filesList.postValue(response.body()); + } + else { + + progressBar.setVisibility(View.GONE); + noDataFiles.setVisibility(View.VISIBLE); + } + } + else { + + progressBar.setVisibility(View.GONE); + noDataFiles.setVisibility(View.VISIBLE); } } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.i("onFailure", t.toString()); + + Toasty.error(ctx, ctx.getString(R.string.errorOnLogin)); } }); } - public LiveData> getFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, String ref, Context ctx) { + public LiveData> getFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, String ref, Context ctx, ProgressBar progressBar, TextView noDataFiles) { filesList2 = new MutableLiveData<>(); - loadFilesList2(instanceUrl, token, owner, repo, filesDir, ref, ctx); + loadFilesList2(instanceUrl, token, owner, repo, filesDir, ref, ctx, progressBar, noDataFiles); return filesList2; } - private static void loadFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, String ref, final Context ctx) { + private static void loadFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, String ref, final Context ctx, ProgressBar progressBar, TextView noDataFiles) { Call> call = RetrofitClient .getInstance(instanceUrl, ctx) @@ -87,23 +99,32 @@ public class FilesViewModel extends ViewModel { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { - if (response.isSuccessful()) { + if (response.code() == 200) { assert response.body() != null; - Collections.sort(response.body(), (byType1, byType2) -> byType1.getType().compareTo(byType2.getType())); - filesList2.postValue(response.body()); - } else { + if(response.body().size() > 0) { - Toasty.warning(ctx, ctx.getString(R.string.noDataFilesTab)); - Log.i("onResponse", String.valueOf(response.code())); + Collections.sort(response.body(), (byType1, byType2) -> byType1.getType().compareTo(byType2.getType())); + filesList2.postValue(response.body()); + } + else { + + progressBar.setVisibility(View.GONE); + noDataFiles.setVisibility(View.VISIBLE); + } } + else { + progressBar.setVisibility(View.GONE); + noDataFiles.setVisibility(View.VISIBLE); + } } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.i("onFailure", t.toString()); + + Toasty.error(ctx, ctx.getString(R.string.errorOnLogin)); } }); 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"> + + + + + + + + + + + + + + + + + + + + + +