diff --git a/.gitea/issue_template.md b/.gitea/issue_template.md index 7551ec81..d1307a05 100644 --- a/.gitea/issue_template.md +++ b/.gitea/issue_template.md @@ -1,32 +1,37 @@ ## # What do you want to address? -(This step is required; examples are shown below) + - [ ] Bug - [ ] Feature - [ ] Suggestion ## # Describe your matter briefly -(This step is required) + +

- -##### What did you expect? (Useful when addressing bugs) +##### What did you expect? --- -_(This step is optional)_ + +

- -##### Some additional details (Useful, when we are trying to reproduce a bug) +##### Some additional details --- -_(This step is optional; an example is shown below)_ + * The version of **Gitea** you are using: * The version of **GitNex** you are using: -* Phone **OS** version and model: -* The type of certificate you are using (self-signed, signed): +* Source of installation (Play Store, F-Droid, APK): +* Current android version and phone model/manufacturer: +* The type of certificate your instance is using (self-signed, signed): * How you used to log in (via password or token): - +
##### We would appreciate some screenshots or stacktrace's, but this is also not required. --- -_(Screenshots and stacktrace's can go here)_ + +

+ +- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/master/CONTRIBUTING.md). +
#### Thank you for your time. \ No newline at end of file diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md index d5a4d998..dd43dcc3 100644 --- a/.gitea/pull_request_template.md +++ b/.gitea/pull_request_template.md @@ -1,8 +1,9 @@ -Please check the following: +### Describe what your pull request does and which issue you’re targeting + +

-1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes. -2. Read contributing guidelines: [CONTRIBUTING.md](https://gitea.com/GitNex/GitNex/src/branch/master/CONTRIBUTING.md) -3. Please follow the [Code-Standards](https://gitea.com/gitnex/GitNex/wiki/Code-Standards) -4. Describe what your pull request does and which issue you’re targeting (create one if does not exist) + -**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.** +- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/master/CONTRIBUTING.md). +- [ ] I'm following the code standards as defined [here](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards). +- [ ] By submitting this pull request, I permit GitNex to license my work under the [GNU General Public License v3](https://codeberg.org/GitNex/GitNex/src/branch/master/LICENSE). \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 78aa8157..40c66e59 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -180,4 +180,4 @@ - + \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a98f6ed1..43385f65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,26 +2,35 @@ Please take a few minutes to read this document to make the process of contribution more easy and healthy for all involved. -## Pull Requests -Patches, enhancements, features are always welcome. The PR should focus on the scope of work and avoid many unnecessary commits. Please provide as much detail and context as possible to explain the work submitted. +### General +> **Be polite and gentle while commenting or creating new issues to maintain a healthy environment in which __everyone__ is able to feel comfortable.** +
-Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work. +### Issues and Reports +Before creating an issue please take a moment and search the repository issues(open/closed) to avoid duplicate issues either it's a bug or feature. +In case you want to submit a bug report, please provide as much details as possible to better debug the problem. The important part is how to reproduce the bug and steps to reproduce are appreciated.

+**Note:** Please contact the project directly via [email](mailto:gitnex@swatian.com) if have to share sensitive and security related details. +
-**Code Standards** +### Pull Requests +Patches, enhancements and features are always welcome. +The PR should focus on the scope of work and avoid many unnecessary commits. +Please provide as much detail and context as possible to explain the work submitted. + +**Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.** (Submit an issue, __before__ submitting a PR) + +**Code Standards**

Please follow the code standards, this will help other developers to understand your code too. It also helps maintaining the code afterwards. It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards) -**How to submit a PR** -Fork this repository. Pull the forked repository from your namespace to your local machine. Create new branch and work on the bug/feature/enhancement you would like to submit. Push it to your forked version. From there create Pull Request(PR) against **master** branch. +**How to submit a PR (Pull Request)** +1. Fork this repository. +2. Clone the forked repository from your namespace to your local machine. +3. Create a new branch and work on your feature, enhancement or patch. +4. Push your commits to your forked version. +5. You can now create a PR using the web interface against **master** branch. -**IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex. +For more information, click [here](http://makeapullrequest.com/). -## Issues and Reports -*1st of please be polite and gentle while commenting or creating new issue to maintain a healthy environment.* - -Before creating an issue please take a moment and search the repository issues(open/closed) to avoid duplicate issues either it's a bug or feature. - -In case you want to submit a bug report, please provide as much details as possible to better debug the problem. The important part is how to reproduce the bug and steps to reproduce are appreciated. - -**Note:** Please contact the project directly via email(gitnex@swatian.com) if have to share sensitive and security related details. +**IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex. \ No newline at end of file diff --git a/README.md b/README.md index e6ac43f6..a03a0cb7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ![Pipeline status](https://img.shields.io/gitlab/pipeline/opyale/gitnex/master) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf) +[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Pipeline status](https://img.shields.io/gitlab/pipeline/opyale/gitnex/master)](https://gitlab.com/opyale/gitnex/-/pipelines) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf) -[Become a Patroen](https://www.patreon.com/mmarif) [Donate using Liberapay](https://liberapay.com/mmarif/donate) +[Become a Patroen](https://www.patreon.com/mmarif) # GitNex - Android client for Gitea @@ -11,7 +11,7 @@ GitNex is licensed under GPLv3 License. See the LICENSE file for the full licens ## Downloads [Get it on F-droid](https://f-droid.org/en/packages/org.mian.gitnex/) [Get it on Google Play](https://play.google.com/store/apps/details?id=org.mian.gitnex.pro) -[Download builds and releases](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE) +[Download builds and releases](https://cloud.swatian.com/s/DN7E5xxtaw4fRbE) ## Note about Gitea version Please make sure that you are on latest stable release or later for better app experience. @@ -74,11 +74,11 @@ Thanks to all the open source libraries, contributors and donators. - Okhttp - Picasso - Markwon +- Prism4j - Prettytime - Amulyakhare/textdrawable - Vdurmont/emoji-java - Pes/materialcolorpicker -- Hendraanggrian/socialview - HamidrezaAmz/BreadcrumbsView - Chrisbanes/PhotoView - Pddstudio/highlightjs-android diff --git a/app/build.gradle b/app/build.gradle index 54a3b468..1c8913b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "org.mian.gitnex" minSdkVersion 21 targetSdkVersion 30 - versionCode 327 - versionName "3.3.0-dev" + versionCode 346 + versionName "3.5.0-dev" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -38,8 +38,10 @@ android { abortOnError false } compileOptions { - targetCompatibility = "8" - sourceCompatibility = "8" + coreLibraryDesugaringEnabled true + + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig{ vectorDrawables.useSupportLibrary = true @@ -52,18 +54,18 @@ configurations { } dependencies { - def lifecycle_version = '2.3.0-beta01' - def markwon_version = '4.6.0' + def lifecycle_version = '2.3.0-rc01' + def markwon_version = '4.6.1' def work_version = "2.4.0" - def acra = "5.5.0" + def acra = "5.7.0" implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.3.0-alpha02' implementation 'com.google.android.material:material:1.3.0-alpha03' - implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" - testImplementation "junit:junit:4.13" + testImplementation 'junit:junit:4.13.1' androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' implementation 'com.squareup.okhttp3:okhttp:4.9.0' @@ -74,8 +76,7 @@ dependencies { implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' - implementation 'org.ocpsoft.prettytime:prettytime:4.0.6.Final' - implementation "com.vdurmont:emoji-java:5.1.1" + implementation 'org.ocpsoft.prettytime:prettytime:5.0.0.Final' implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:ext-latex:$markwon_version" @@ -90,10 +91,11 @@ dependencies { implementation "io.noties.markwon:recycler-table:$markwon_version" implementation "io.noties.markwon:simple-ext:$markwon_version" implementation "io.noties.markwon:syntax-highlight:$markwon_version" + implementation "io.noties.markwon:image-picasso:$markwon_version" + implementation "io.noties:prism4j:2.0.0" + annotationProcessor "io.noties:prism4j-bundler:2.0.0" implementation "com.caverock:androidsvg:1.4" - implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.19" - implementation "com.hendraanggrian.appcompat:socialview:0.2" - implementation "com.hendraanggrian.appcompat:socialview-commons:0.2" + implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.21" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" implementation "commons-io:commons-io:20030203.000550" implementation 'org.apache.commons:commons-lang3:3.11' @@ -102,10 +104,12 @@ dependencies { implementation "ch.acra:acra-mail:$acra" implementation "ch.acra:acra-limiter:$acra" implementation "ch.acra:acra-notification:$acra" - implementation "androidx.room:room-runtime:2.2.5" - annotationProcessor "androidx.room:room-compiler:2.2.5" + implementation 'androidx.room:room-runtime:2.2.6' + annotationProcessor 'androidx.room:room-compiler:2.2.6' implementation "androidx.work:work-runtime:$work_version" - implementation "com.eightbitlab:blurview:1.6.3" + implementation "com.eightbitlab:blurview:1.6.4" implementation "io.mikael:urlbuilder:2.0.9" + implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2" + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ddfa3c9f..80e1c62d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + - + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/app_logo-playstore.png b/app/src/main/app_logo-playstore.png index f78fac3d..b5690e64 100644 Binary files a/app/src/main/app_logo-playstore.png and b/app/src/main/app_logo-playstore.png differ diff --git a/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java b/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java index c013e970..a2fd5895 100644 --- a/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/AssigneesActions.java @@ -24,12 +24,11 @@ import retrofit2.Callback; public class AssigneesActions { - public static void getCurrentIssueAssignees(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List currentAssignees) { + public static void getCurrentIssueAssignees(Context ctx, String repoOwner, String repoName, int issueIndex, List currentAssignees) { Call callSingleIssueLabels = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + .getApiInterface(ctx) + .getIssueByIndex(Authorization.get(ctx), repoOwner, repoName, issueIndex); callSingleIssueLabels.enqueue(new Callback() { @@ -63,14 +62,13 @@ public class AssigneesActions { }); } - public static void getRepositoryAssignees(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List assigneesList, Dialog dialogAssignees, AssigneesListAdapter assigneesAdapter, CustomAssigneesSelectionDialogBinding assigneesBinding) { + public static void getRepositoryAssignees(Context ctx, String repoOwner, String repoName, List assigneesList, Dialog dialogAssignees, AssigneesListAdapter assigneesAdapter, CustomAssigneesSelectionDialogBinding assigneesBinding) { - TinyDB tinyDB = new TinyDB(ctx); + TinyDB tinyDB = TinyDB.getInstance(ctx); Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getCollaborators(instanceToken, repoOwner, repoName); + .getApiInterface(ctx) + .getCollaborators(Authorization.get(ctx), repoOwner, repoName); call.enqueue(new Callback>() { @@ -89,8 +87,6 @@ public class AssigneesActions { if(assigneesList_.size() > 0) { - dialogAssignees.show(); - assigneesList.add(new Collaborators(tinyDB.getString("userFullname"), tinyDB.getString("loginUid"), tinyDB.getString("userAvatar"))); assigneesList.addAll(assigneesList_); } diff --git a/app/src/main/java/org/mian/gitnex/actions/CollaboratorActions.java b/app/src/main/java/org/mian/gitnex/actions/CollaboratorActions.java index 03bb66fa..bd0d988a 100644 --- a/app/src/main/java/org/mian/gitnex/actions/CollaboratorActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/CollaboratorActions.java @@ -25,21 +25,16 @@ public class CollaboratorActions { public static void deleteCollaborator(final Context context, final String searchKeyword, String userName) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - Call call; - - call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .deleteCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName); + Call call = RetrofitClient + .getApiInterface(context) + .deleteCollaborator(Authorization.get(context), repoOwner, repoName, userName); call.enqueue(new Callback() { @@ -54,7 +49,7 @@ public class CollaboratorActions { //Log.i("addCollaboratorSearch", addCollaboratorSearch.getText().toString()); //tinyDb.putBoolean("updateDataSet", true); //AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity(); - //usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context); + //usersSearchData.loadUserSearchList(instanceToken, searchKeyword, context); } } @@ -94,22 +89,18 @@ public class CollaboratorActions { public static void addCollaborator(final Context context, String permission, String userName) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; Permission permissionString = new Permission(permission); - Call call; - call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .addCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName, permissionString); + Call call = RetrofitClient + .getApiInterface(context) + .addCollaborator(Authorization.get(context), repoOwner, repoName, userName, permissionString); call.enqueue(new Callback() { @@ -122,7 +113,7 @@ public class CollaboratorActions { Toasty.success(context, context.getString(R.string.addCollaboratorToastText)); ((AddCollaboratorToRepositoryActivity)context).finish(); //AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity(); - //usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context); + //usersSearchData.loadUserSearchList(instanceToken, searchKeyword, context); } } @@ -164,11 +155,7 @@ public class CollaboratorActions { public static ActionResult> getCollaborators(Context context) { ActionResult> actionResult = new ActionResult<>(); - TinyDB tinyDb = new TinyDB(context); - - String instanceUrl = tinyDb.getString("instanceUrl"); - String loginUid = tinyDb.getString("loginUid"); - String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(context); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); @@ -176,9 +163,8 @@ public class CollaboratorActions { String repoName = parts[1]; Call> call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .getCollaborators(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(context) + .getCollaborators(Authorization.get(context), repoOwner, repoName); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/actions/IssueActions.java b/app/src/main/java/org/mian/gitnex/actions/IssueActions.java index 57b68b11..79244e18 100644 --- a/app/src/main/java/org/mian/gitnex/actions/IssueActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/IssueActions.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import com.google.gson.JsonElement; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.database.api.DraftsApi; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; @@ -15,6 +14,7 @@ import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.UpdateIssueState; import retrofit2.Call; import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -22,85 +22,72 @@ import retrofit2.Callback; public class IssueActions { - public static void editIssueComment(final Context ctx, final int commentId, final String commentBody, long draftIdOnCreate) { + public static ActionResult> edit(Context context, String comment, int commentId) { + + ActionResult> actionResult = new ActionResult<>(); + + TinyDB tinyDb = TinyDB.getInstance(context); - final TinyDB tinyDb = new TinyDB(ctx); - 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]; - IssueComments commentBodyJson = new IssueComments(commentBody); - Call call; + String repoOwner = parts[0]; + String repoName = parts[1]; - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().patchIssueComment(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson); + Call call = RetrofitClient + .getApiInterface(context) + .patchIssueComment(Authorization.get(context), repoOwner, repoName, commentId, new IssueComments(comment)); call.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if(response.isSuccessful()) { - if(response.code() == 200) { + switch(response.code()) { - tinyDb.putBoolean("commentEdited", true); - Toasty.info(ctx, ctx.getString(R.string.editCommentUpdatedText)); + case 200: + actionResult.finish(ActionResult.Status.SUCCESS); + break; - DraftsApi draftsApi = new DraftsApi(ctx); - draftsApi.deleteSingleDraft((int) draftIdOnCreate); + case 401: + actionResult.finish(ActionResult.Status.FAILED, response); + AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle), context.getResources().getString(R.string.alertDialogTokenRevokedMessage), context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + break; - } - } - else if(response.code() == 401) { - - AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + default: + actionResult.finish(ActionResult.Status.FAILED, response); + break; } - 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, ctx.getString(R.string.genericError)); - - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); + actionResult.finish(ActionResult.Status.FAILED); } }); + return actionResult; + } public static void closeReopenIssue(final Context ctx, final int issueIndex, final String issueState) { - final TinyDB tinyDb = new TinyDB(ctx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(ctx); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; final String repoName = parts[1]; UpdateIssueState issueStatJson = new UpdateIssueState(issueState); Call call; - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().closeReopenIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson); + call = RetrofitClient + .getApiInterface(ctx) + .closeReopenIssue(Authorization.get(ctx), repoOwner, repoName, issueIndex, issueStatJson); call.enqueue(new Callback() { @@ -162,20 +149,23 @@ public class IssueActions { public static void subscribe(final Context ctx) { - final TinyDB tinyDB = new TinyDB(ctx); + final TinyDB tinyDB = TinyDB.getInstance(ctx); - final String instanceUrl = tinyDB.getString("instanceUrl"); String[] repoFullName = tinyDB.getString("repoFullName").split("/"); + if(repoFullName.length != 2) { return; } + final String userLogin = tinyDB.getString("userLogin"); final String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token"); final int issueNr = Integer.parseInt(tinyDB.getString("issueNumber")); Call call; - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().addIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin); + call = RetrofitClient + .getApiInterface(ctx) + .addIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin); call.enqueue(new Callback() { @@ -222,9 +212,8 @@ public class IssueActions { public static void unsubscribe(final Context ctx) { - final TinyDB tinyDB = new TinyDB(ctx); + final TinyDB tinyDB = TinyDB.getInstance(ctx); - final String instanceUrl = tinyDB.getString("instanceUrl"); String[] repoFullName = tinyDB.getString("repoFullName").split("/"); if(repoFullName.length != 2) { return; @@ -235,7 +224,7 @@ public class IssueActions { Call call; - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().delIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin); + call = RetrofitClient.getApiInterface(ctx).delIssueSubscriber(token, repoFullName[0], repoFullName[1], issueNr, userLogin); call.enqueue(new Callback() { @@ -282,11 +271,8 @@ public class IssueActions { public static ActionResult reply(Context context, String comment, int issueIndex) { ActionResult actionResult = new ActionResult<>(); - TinyDB tinyDb = new TinyDB(context); - String instanceUrl = tinyDb.getString("instanceUrl"); - String loginUid = tinyDb.getString("loginUid"); - String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(context); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); @@ -296,9 +282,8 @@ public class IssueActions { Issues issueComment = new Issues(comment); Call call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .replyCommentToIssue(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment); + .getApiInterface(context) + .replyCommentToIssue(Authorization.get(context), repoOwner, repoName, issueIndex, issueComment); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java b/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java index e6338617..72c48521 100644 --- a/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/LabelsActions.java @@ -22,12 +22,11 @@ import retrofit2.Callback; public class LabelsActions { - public static void getCurrentIssueLabels(Context ctx, String instanceUrl, String loginUid, String instanceToken, String repoOwner, String repoName, int issueIndex, List currentLabelsIds) { + public static void getCurrentIssueLabels(Context ctx, String repoOwner, String repoName, int issueIndex, List currentLabelsIds) { Call> callSingleIssueLabels = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + .getApiInterface(ctx) + .getIssueLabels(Authorization.get(ctx), repoOwner, repoName, issueIndex); callSingleIssueLabels.enqueue(new Callback>() { @@ -60,12 +59,11 @@ public class LabelsActions { }); } - public static void getRepositoryLabels(Context ctx, String instanceUrl, String instanceToken, String repoOwner, String repoName, List labelsList, Dialog dialogLabels, LabelsListAdapter labelsAdapter, CustomLabelsSelectionDialogBinding labelsBinding) { + public static void getRepositoryLabels(Context ctx, String repoOwner, String repoName, List labelsList, Dialog dialogLabels, LabelsListAdapter labelsAdapter, CustomLabelsSelectionDialogBinding labelsBinding) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getlabels(instanceToken, repoOwner, repoName); + .getApiInterface(ctx) + .getLabels(Authorization.get(ctx), repoOwner, repoName); call.enqueue(new Callback>() { @@ -73,28 +71,45 @@ public class LabelsActions { 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(response.body() != null) { - if(labelsList_.size() > 0) { - - dialogLabels.show(); - - labelsList.addAll(labelsList_); - } - else { - - dialogLabels.dismiss(); - Toasty.warning(ctx, ctx.getResources().getString(R.string.noLabelsFound)); + labelsList.addAll(response.body()); } - labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter); + // Load organization labels + Call> callOrgLabels = RetrofitClient + .getApiInterface(ctx) + .getOrganizationLabels(Authorization.get(ctx), repoOwner); + + callOrgLabels.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> responseOrg) { + + labelsBinding.progressBar.setVisibility(View.GONE); + labelsBinding.dialogFrame.setVisibility(View.VISIBLE); + + if(responseOrg.body() != null) { + + labelsList.addAll(responseOrg.body()); + } + + if(labelsList.isEmpty()) { + + dialogLabels.dismiss(); + Toasty.warning(ctx, ctx.getResources().getString(R.string.noLabelsFound)); + + } + + labelsBinding.labelsRecyclerView.setAdapter(labelsAdapter); + } + + @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) {} + + }); } else { diff --git a/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java b/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java index bf3d8358..fbe21173 100644 --- a/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java @@ -23,9 +23,8 @@ public class MilestoneActions { public static void closeMilestone(final Context ctx, int milestoneId_) { - final TinyDB tinyDB = new TinyDB(ctx); + final TinyDB tinyDB = TinyDB.getInstance(ctx); - final String instanceUrl = tinyDB.getString("instanceUrl"); String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -37,8 +36,7 @@ public class MilestoneActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson); call.enqueue(new Callback() { @@ -81,9 +79,8 @@ public class MilestoneActions { public static void openMilestone(final Context ctx, int milestoneId_) { - final TinyDB tinyDB = new TinyDB(ctx); + final TinyDB tinyDB = TinyDB.getInstance(ctx); - final String instanceUrl = tinyDB.getString("instanceUrl"); String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -95,8 +92,7 @@ public class MilestoneActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .closeReopenMilestone(token, repoOwner, repoName, milestoneId_, milestoneStateJson); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java b/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java index 35239248..0ea9da90 100644 --- a/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java @@ -20,24 +20,22 @@ public class NotificationsActions { private TinyDB tinyDB; private Context context; - private String instanceUrl; private String instanceToken; public NotificationsActions(Context context) { this.context = context; - this.tinyDB = new TinyDB(context); + this.tinyDB = TinyDB.getInstance(context); String loginUid = tinyDB.getString("loginUid"); - instanceUrl = tinyDB.getString("instanceUrl"); instanceToken = "token " + tinyDB.getString(loginUid + "-token"); } public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException { - Call call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface() + Call call = RetrofitClient.getApiInterface(context) .markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name()); if(!call.execute().isSuccessful()) { @@ -48,7 +46,7 @@ public class NotificationsActions { public boolean setAllNotificationsRead(Date date) throws IOException { - Call call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface() + Call call = RetrofitClient.getApiInterface(context) .markNotificationThreadsAsRead(instanceToken, AppUtil.getTimestampFromDate(context, date), true, new String[]{"unread", "pinned"}, "read"); diff --git a/app/src/main/java/org/mian/gitnex/actions/RepositoryActions.java b/app/src/main/java/org/mian/gitnex/actions/RepositoryActions.java index da7e80f7..f4e0d9fb 100644 --- a/app/src/main/java/org/mian/gitnex/actions/RepositoryActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/RepositoryActions.java @@ -21,10 +21,8 @@ public class RepositoryActions { public static void starRepository(final Context context) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -33,9 +31,8 @@ public class RepositoryActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .starRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(context) + .starRepository(Authorization.get(context), repoOwner, repoName); call.enqueue(new Callback() { @@ -86,10 +83,8 @@ public class RepositoryActions { public static void unStarRepository(final Context context) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -98,9 +93,8 @@ public class RepositoryActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .unStarRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(context) + .unStarRepository(Authorization.get(context), repoOwner, repoName); call.enqueue(new Callback() { @@ -151,10 +145,8 @@ public class RepositoryActions { public static void watchRepository(final Context context) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -163,9 +155,8 @@ public class RepositoryActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .watchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(context) + .watchRepository(Authorization.get(context), repoOwner, repoName); call.enqueue(new Callback() { @@ -216,10 +207,8 @@ public class RepositoryActions { public static void unWatchRepository(final Context context) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); + String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -228,9 +217,8 @@ public class RepositoryActions { Call call; call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .unWatchRepository(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(context) + .unWatchRepository(Authorization.get(context), repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/actions/TeamActions.java b/app/src/main/java/org/mian/gitnex/actions/TeamActions.java index 28a854cc..e97a0b9e 100644 --- a/app/src/main/java/org/mian/gitnex/actions/TeamActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/TeamActions.java @@ -21,17 +21,13 @@ public class TeamActions { public static void removeTeamMember(final Context context, String userName, int teamId) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); Call call; call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .removeTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName); + .getApiInterface(context) + .removeTeamMember(Authorization.get(context), teamId, userName); call.enqueue(new Callback() { @@ -87,17 +83,11 @@ public class TeamActions { public static void addTeamMember(final Context context, String userName, int teamId) { - final TinyDB tinyDb = new TinyDB(context); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final TinyDB tinyDb = TinyDB.getInstance(context); - Call call; - - call = RetrofitClient - .getInstance(instanceUrl, context) - .getApiInterface() - .addTeamMember(Authorization.returnAuthentication(context, loginUid, instanceToken), teamId, userName); + Call call = RetrofitClient + .getApiInterface(context) + .addTeamMember(Authorization.get(context), teamId, userName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/activities/AddCollaboratorToRepositoryActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddCollaboratorToRepositoryActivity.java index f438f4db..80e17d01 100644 --- a/app/src/main/java/org/mian/gitnex/activities/AddCollaboratorToRepositoryActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/AddCollaboratorToRepositoryActivity.java @@ -17,7 +17,6 @@ import org.mian.gitnex.R; import org.mian.gitnex.adapters.UserSearchAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserSearch; import java.util.List; @@ -32,8 +31,6 @@ import retrofit2.Response; public class AddCollaboratorToRepositoryActivity extends BaseActivity { private View.OnClickListener onClickListener; - final Context ctx = this; - private Context appCtx; private TextView addCollaboratorSearch; private TextView noData; private ProgressBar mProgressBar; @@ -49,21 +46,13 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); 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"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - ImageView closeActivity = findViewById(R.id.close); addCollaboratorSearch = findViewById(R.id.addCollaboratorSearch); mRecyclerView = findViewById(R.id.recyclerViewUserSearch); - mProgressBar = findViewById(R.id.progress_bar); + mProgressBar = findViewById(R.id.progressBar); noData = findViewById(R.id.noData); addCollaboratorSearch.requestFocus(); @@ -76,8 +65,11 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity { addCollaboratorSearch.setOnEditorActionListener((v, actionId, event) -> { if (actionId == EditorInfo.IME_ACTION_SEND) { + if(!addCollaboratorSearch.getText().toString().equals("")) { - loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), loginUid); + + mProgressBar.setVisibility(View.VISIBLE); + loadUserSearchList(addCollaboratorSearch.getText().toString()); } } @@ -87,22 +79,26 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity { } - public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, String loginUid) { + public void loadUserSearchList(String searchKeyword) { Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10); + .getApiInterface(appCtx) + .getUserBySearch(Authorization.get(ctx), searchKeyword, 10); call.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { + mProgressBar.setVisibility(View.GONE); + + if (response.code() == 200) { + assert response.body() != null; getUsersList(response.body().getData(), ctx); - } else { + } + else { + Log.i("onResponse", String.valueOf(response.code())); } @@ -129,15 +125,16 @@ public class AddCollaboratorToRepositoryActivity extends BaseActivity { mProgressBar.setVisibility(View.VISIBLE); if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); noData.setVisibility(View.GONE); - mProgressBar.setVisibility(View.GONE); } else { + noData.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); } + mProgressBar.setVisibility(View.GONE); } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java index cc89cb43..d0b76ccb 100644 --- a/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java @@ -1,6 +1,5 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; @@ -15,7 +14,6 @@ import org.mian.gitnex.database.api.UserAccountsApi; import org.mian.gitnex.databinding.ActivityAddNewAccountBinding; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.PathsHelper; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.UrlHelper; import org.mian.gitnex.helpers.Version; @@ -32,10 +30,6 @@ import retrofit2.Callback; public class AddNewAccountActivity extends BaseActivity { - final Context ctx = this; - private Context appCtx; - private TinyDB tinyDB; - private View.OnClickListener onClickListener; private ActivityAddNewAccountBinding viewBinding; @@ -52,8 +46,6 @@ public class AddNewAccountActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDB = new TinyDB(appCtx); viewBinding = ActivityAddNewAccountBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); @@ -76,7 +68,6 @@ public class AddNewAccountActivity extends BaseActivity { if(!connToInternet) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); - } else { @@ -132,7 +123,7 @@ public class AddNewAccountActivity extends BaseActivity { Call callVersion; - callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken("token " + loginToken); + callVersion = RetrofitClient.getApiInterface(ctx).getGiteaVersionWithToken("token " + loginToken); callVersion.enqueue(new Callback() { @@ -144,7 +135,9 @@ public class AddNewAccountActivity extends BaseActivity { GiteaVersion version = responseVersion.body(); assert version != null; + if(!Version.valid(version.getVersion())) { + Toasty.error(ctx, getResources().getString(R.string.versionUnknown)); return; } @@ -170,7 +163,6 @@ public class AddNewAccountActivity extends BaseActivity { }); alertDialogBuilder.create().show(); - } else if(giteaVersion.lessOrEqual(getString(R.string.versionHigh))) { @@ -180,7 +172,6 @@ public class AddNewAccountActivity extends BaseActivity { Toasty.warning(ctx, getResources().getString(R.string.versionUnsupportedNew)); login(instanceUrl, loginToken); - } } @@ -193,7 +184,6 @@ public class AddNewAccountActivity extends BaseActivity { private void login(String instanceUrl, String loginToken) { setupNewAccountWithToken(instanceUrl, loginToken); - } @Override @@ -207,7 +197,7 @@ public class AddNewAccountActivity extends BaseActivity { private void setupNewAccountWithToken(String instanceUrl, final String loginToken) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken); + Call call = RetrofitClient.getApiInterface(ctx, instanceUrl).getUserInfo("token " + loginToken); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/activities/AddNewTeamMemberActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddNewTeamMemberActivity.java index 2085cf13..11b65d02 100644 --- a/app/src/main/java/org/mian/gitnex/activities/AddNewTeamMemberActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/AddNewTeamMemberActivity.java @@ -18,7 +18,6 @@ import org.mian.gitnex.R; import org.mian.gitnex.adapters.UserSearchForTeamMemberAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserSearch; import java.util.ArrayList; @@ -35,8 +34,6 @@ import retrofit2.Response; public class AddNewTeamMemberActivity extends BaseActivity { private View.OnClickListener onClickListener; - final Context ctx = this; - private Context appCtx; private TextView addNewTeamMember; private TextView noData; private ProgressBar mProgressBar; @@ -56,17 +53,9 @@ public class AddNewTeamMemberActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); 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"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - ImageView closeActivity = findViewById(R.id.close); addNewTeamMember = findViewById(R.id.addNewTeamMember); mRecyclerView = findViewById(R.id.recyclerViewUserSearch); @@ -81,9 +70,11 @@ public class AddNewTeamMemberActivity extends BaseActivity { closeActivity.setOnClickListener(onClickListener); if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")) { + teamId = getIntent().getStringExtra("teamId"); } else { + teamId = "0"; } @@ -103,10 +94,8 @@ public class AddNewTeamMemberActivity extends BaseActivity { if(!addNewTeamMember.getText().toString().equals("") && addNewTeamMember.getText().toString().length() > 1) { adapter = new UserSearchForTeamMemberAdapter(dataList, ctx, Integer.parseInt(teamId)); - loadUserSearchList(instanceUrl, instanceToken, addNewTeamMember.getText().toString(), loginUid, teamId); - + loadUserSearchList(addNewTeamMember.getText().toString(), teamId); } - } @Override @@ -121,9 +110,9 @@ public class AddNewTeamMemberActivity extends BaseActivity { } - public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, String loginUid, String teamId) { + public void loadUserSearchList(String searchKeyword, String teamId) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserBySearch(Authorization.returnAuthentication(ctx, loginUid, token), searchKeyword, 10); + Call call = RetrofitClient.getApiInterface(ctx).getUserBySearch(Authorization.get(ctx), searchKeyword, 10); mProgressBar.setVisibility(View.VISIBLE); @@ -141,16 +130,13 @@ public class AddNewTeamMemberActivity extends BaseActivity { dataList.addAll(response.body().getData()); mRecyclerView.setAdapter(adapter); noData.setVisibility(View.GONE); - mProgressBar.setVisibility(View.GONE); - } else { noData.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - } + mProgressBar.setVisibility(View.GONE); } } diff --git a/app/src/main/java/org/mian/gitnex/activities/AdminGetUsersActivity.java b/app/src/main/java/org/mian/gitnex/activities/AdminGetUsersActivity.java index c49bbab0..07addcf7 100644 --- a/app/src/main/java/org/mian/gitnex/activities/AdminGetUsersActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/AdminGetUsersActivity.java @@ -24,7 +24,6 @@ import org.mian.gitnex.adapters.AdminGetUsersAdapter; import org.mian.gitnex.fragments.BottomSheetAdminUsersFragment; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.viewmodels.AdminGetUsersViewModel; /** @@ -34,8 +33,6 @@ import org.mian.gitnex.viewmodels.AdminGetUsersViewModel; public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAdminUsersFragment.BottomSheetListener { private View.OnClickListener onClickListener; - final Context ctx = this; - private Context appCtx; private AdminGetUsersAdapter adapter; private RecyclerView mRecyclerView; private TextView noDataUsers; @@ -50,12 +47,6 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - 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"); ImageView closeActivity = findViewById(R.id.close); noDataUsers = findViewById(R.id.noDataUsers); @@ -79,30 +70,30 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - AdminGetUsersViewModel.loadUsersList(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken)); + AdminGetUsersViewModel.loadUsersList(ctx, Authorization.get(ctx)); }, 500)); - fetchDataAsync(ctx, instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken)); + fetchDataAsync(ctx, Authorization.get(ctx)); } - private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) { + private void fetchDataAsync(Context ctx, String instanceToken) { AdminGetUsersViewModel usersModel = new ViewModelProvider(this).get(AdminGetUsersViewModel.class); - usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, usersListMain -> { + usersModel.getUsersList(ctx, instanceToken).observe(this, usersListMain -> { adapter = new AdminGetUsersAdapter(ctx, usersListMain); if(adapter.getItemCount() > 0) { + mRecyclerView.setVisibility(View.VISIBLE); mRecyclerView.setAdapter(adapter); noDataUsers.setVisibility(View.GONE); searchFilter = true; } else { - //adapter.notifyDataSetChanged(); - //mRecyclerView.setAdapter(adapter); + mRecyclerView.setVisibility(View.GONE); noDataUsers.setVisibility(View.VISIBLE); } @@ -140,6 +131,7 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd @Override public boolean onQueryTextChange(String newText) { + adapter.getFilter().filter(newText); return false; } @@ -157,18 +149,21 @@ public class AdminGetUsersActivity extends BaseActivity implements BottomSheetAd int id = item.getItemId(); - switch (id) { - case android.R.id.home: - finish(); - return true; - case R.id.genericMenu: - BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment(); - bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } + if(id == android.R.id.home) { + finish(); + return true; + } + else if(id == R.id.genericMenu) { + + BottomSheetAdminUsersFragment bottomSheet = new BottomSheetAdminUsersFragment(); + bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet"); + return true; + } + else { + + return super.onOptionsItemSelected(item); + } } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java b/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java index 87007716..4fb677d0 100644 --- a/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java @@ -1,5 +1,6 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; @@ -14,6 +15,7 @@ import org.acra.data.StringFormat; import org.mian.gitnex.R; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.FontsOverride; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.notifications.NotificationsMaster; @@ -25,6 +27,7 @@ import static org.acra.ReportField.STACK_TRACE; * Author M M Arif */ +@SuppressLint("NonConstantResourceId") @AcraNotification(resIcon = R.drawable.gitnex_transparent, resTitle = R.string.crashTitle, resChannelName = R.string.setCrashReports, @@ -33,119 +36,144 @@ import static org.acra.ReportField.STACK_TRACE; public abstract class BaseActivity extends AppCompatActivity { - private Context appCtx; + protected TinyDB tinyDB; + + protected Context ctx = this; + protected Context appCtx; @Override public void onCreate(Bundle savedInstanceState) { - appCtx = getApplicationContext(); - final TinyDB tinyDb = new TinyDB(appCtx); + this.appCtx = getApplicationContext(); + this.tinyDB = TinyDB.getInstance(appCtx); - switch(tinyDb.getInt("themeId")) { + switch(tinyDB.getInt("themeId")) { case 1: + + tinyDB.putString("currentTheme", "light"); setTheme(R.style.AppThemeLight); break; - case 2: + if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am + + tinyDB.putString("currentTheme", "dark"); setTheme(R.style.AppTheme); } else { + + tinyDB.putString("currentTheme", "light"); setTheme(R.style.AppThemeLight); } break; - case 3: + + tinyDB.putString("currentTheme", "light"); setTheme(R.style.AppThemeRetro); break; - case 4: if(TimeHelper.timeBetweenHours(18, 6)) { // 6pm to 6am + + tinyDB.putString("currentTheme", "dark"); setTheme(R.style.AppTheme); } else { + + tinyDB.putString("currentTheme", "light"); setTheme(R.style.AppThemeRetro); } break; + case 5: - default: - setTheme(R.style.AppTheme); + tinyDB.putString("currentTheme", "dark"); + setTheme(R.style.AppThemePitchBlack); break; + default: + + tinyDB.putString("currentTheme", "dark"); + setTheme(R.style.AppTheme); } - String appLocale = tinyDb.getString("locale"); + String appLocale = tinyDB.getString("locale"); AppUtil.setAppLocale(getResources(), appLocale); super.onCreate(savedInstanceState); setContentView(getLayoutResourceId()); - switch(tinyDb.getInt("customFontId", -1)) { + // FIXME Performance nightmare + switch(tinyDB.getInt("customFontId", -1)) { case 0: + FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "SERIF", "fonts/roboto.ttf"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/roboto.ttf"); break; - case 2: + FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/sourcecodeproregular.ttf"); FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/sourcecodeproregular.ttf"); FontsOverride.setDefaultFont(this, "SERIF", "fonts/sourcecodeproregular.ttf"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/sourcecodeproregular.ttf"); break; - default: + FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "SERIF", "fonts/manroperegular.ttf"); FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/manroperegular.ttf"); - break; - } - if(tinyDb.getInt("pollingDelayMinutes") == 0) { - tinyDb.putInt("pollingDelayMinutes", 15); + if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) { + + tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay); } + // FIXME Performance nightmare NotificationsMaster.hireWorker(appCtx); // enabling counter badges by default - if(tinyDb.getString("enableCounterBadgesInit").isEmpty()) { - tinyDb.putBoolean("enableCounterBadges", true); - tinyDb.putString("enableCounterBadgesInit", "yes"); + if(tinyDB.getString("enableCounterBadgesInit").isEmpty()) { + + tinyDB.putBoolean("enableCounterBadges", true); + tinyDB.putString("enableCounterBadgesInit", "yes"); } // enable crash reports by default - if(tinyDb.getString("crashReportingEnabledInit").isEmpty()) { - tinyDb.putBoolean("crashReportingEnabled", true); - tinyDb.putString("crashReportingEnabledInit", "yes"); + if(tinyDB.getString("crashReportingEnabledInit").isEmpty()) { + + tinyDB.putBoolean("crashReportingEnabled", true); + tinyDB.putString("crashReportingEnabledInit", "yes"); } // default cache setter - if(tinyDb.getString("cacheSizeStr").isEmpty()) { - tinyDb.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText)); + if(tinyDB.getString("cacheSizeStr").isEmpty()) { + + tinyDB.putString("cacheSizeStr", getResources().getString(R.string.cacheSizeDataSelectionSelectedText)); } - if(tinyDb.getString("cacheSizeImagesStr").isEmpty()) { - tinyDb.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText)); + if(tinyDB.getString("cacheSizeImagesStr").isEmpty()) { + + tinyDB.putString("cacheSizeImagesStr", getResources().getString(R.string.cacheSizeImagesSelectionSelectedText)); } // enable comment drafts by default - if(tinyDb.getString("draftsCommentsDeletionEnabledInit").isEmpty()) { - tinyDb.putBoolean("draftsCommentsDeletionEnabled", true); - tinyDb.putString("draftsCommentsDeletionEnabledInit", "yes"); + if(tinyDB.getString("draftsCommentsDeletionEnabledInit").isEmpty()) { + + tinyDB.putBoolean("draftsCommentsDeletionEnabled", true); + tinyDB.putString("draftsCommentsDeletionEnabledInit", "yes"); } - if (tinyDb.getBoolean("crashReportingEnabled")) { + // FIXME Performance nightmare + if (tinyDB.getBoolean("crashReportingEnabled")) { CoreConfigurationBuilder ACRABuilder = new CoreConfigurationBuilder(this); ACRABuilder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.KEY_VALUE_LIST); ACRABuilder.getPluginConfigurationBuilder(MailSenderConfigurationBuilder.class).setReportAsFile(true).setMailTo(getResources().getString(R.string.appEmail)).setSubject(getResources().getString(R.string.crashReportEmailSubject, AppUtil.getAppBuildNo(getApplicationContext()))).setEnabled(true); ACRABuilder.getPluginConfigurationBuilder(LimiterConfigurationBuilder.class).setEnabled(true); ACRA.init(getApplication(), ACRABuilder); - } } 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 f360ef3b..59fd7b3b 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java @@ -1,6 +1,5 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -21,13 +20,11 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.adapters.CommitsAdapter; -import org.mian.gitnex.clients.AppApiService; +import org.mian.gitnex.clients.RetrofitClient; 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; import java.util.ArrayList; import java.util.List; @@ -41,8 +38,6 @@ import retrofit2.Response; public class CommitsActivity extends BaseActivity { - final Context ctx = this; - private Context appCtx; private View.OnClickListener onClickListener; private TextView noData; private ProgressBar progressBar; @@ -53,7 +48,6 @@ public class CommitsActivity extends BaseActivity { private RecyclerView recyclerView; private List commitsList; private CommitsAdapter adapter; - private ApiInterface api; private ProgressBar progressLoadMore; @Override @@ -66,15 +60,10 @@ public class CommitsActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - 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 repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; @@ -95,7 +84,8 @@ public class CommitsActivity extends BaseActivity { closeActivity.setOnClickListener(onClickListener); // if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances) - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } @@ -105,9 +95,8 @@ public class CommitsActivity extends BaseActivity { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit); + loadInitial(Authorization.get(ctx), repoOwner, repoName, branchName, resultLimit); adapter.notifyDataChanged(); - }, 200)); adapter = new CommitsAdapter(ctx, commitsList); @@ -116,23 +105,20 @@ public class CommitsActivity extends BaseActivity { if(commitsList.size() == resultLimit || pageSize == resultLimit) { int page = (commitsList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, branchName, resultLimit); + loadMore(Authorization.get(ctx), repoOwner, repoName, page, branchName, resultLimit); } - })); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); recyclerView.setAdapter(adapter); - api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx); - loadInitial(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName, resultLimit); - + loadInitial(Authorization.get(ctx), repoOwner, repoName, branchName, resultLimit); } private void loadInitial(String token, String repoOwner, String repoName, String branchName, int resultLimit) { - Call> call = api.getRepositoryCommits(token, repoOwner, repoName, 1, branchName, resultLimit); + Call> call = RetrofitClient.getApiInterface(ctx).getRepositoryCommits(token, repoOwner, repoName, 1, branchName, resultLimit); call.enqueue(new Callback>() { @@ -148,7 +134,6 @@ public class CommitsActivity extends BaseActivity { commitsList.addAll(response.body()); adapter.notifyDataChanged(); noData.setVisibility(View.GONE); - } else { @@ -164,7 +149,6 @@ public class CommitsActivity extends BaseActivity { else { Log.e(TAG, String.valueOf(response.code())); - } progressBar.setVisibility(View.GONE); @@ -184,7 +168,7 @@ public class CommitsActivity extends BaseActivity { progressLoadMore.setVisibility(View.VISIBLE); - Call> call = api.getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit); + Call> call = RetrofitClient.getApiInterface(ctx).getRepositoryCommits(token, repoOwner, repoName, page, branchName, resultLimit); call.enqueue(new Callback>() { @@ -211,7 +195,6 @@ public class CommitsActivity extends BaseActivity { else { Log.e(TAG, String.valueOf(response.code())); - } progressLoadMore.setVisibility(View.GONE); @@ -255,7 +238,6 @@ public class CommitsActivity extends BaseActivity { }); return super.onCreateOptionsMenu(menu); - } private void filter(String text) { @@ -263,7 +245,9 @@ public class CommitsActivity extends BaseActivity { List arr = new ArrayList<>(); for(Commits d : commitsList) { + if(d.getCommit().getMessage().toLowerCase().contains(text) || d.getSha().toLowerCase().contains(text)) { + arr.add(d); } } @@ -274,6 +258,7 @@ public class CommitsActivity extends BaseActivity { private void initCloseListener() { onClickListener = view -> { + getIntent().removeExtra("branchName"); finish(); }; diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java index 0e6c74ad..d0ed6187 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java @@ -1,16 +1,17 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; 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; @@ -19,7 +20,6 @@ import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.DeleteFile; @@ -44,49 +44,48 @@ public class CreateFileActivity extends BaseActivity { private EditText newFileContent; private EditText newFileBranchName; private EditText newFileCommitMessage; - private Spinner newFileBranchesSpinner; + private AutoCompleteTextView newFileBranchesSpinner; private String filePath; private String fileSha; private int fileAction = 0; // 0 = create, 1 = delete, 2 = edit - final Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; List branchesList = new ArrayList<>(); + private String loginUid; + private String repoOwner; + private String repoName; + private String instanceToken; + + private String selectedBranch; + @Override protected int getLayoutResourceId(){ return R.layout.activity_new_file; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); + 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"); + repoOwner = parts[0]; + repoName = parts[1]; + instanceToken = "token " + tinyDB.getString(loginUid + "-token"); closeActivity = findViewById(R.id.close); newFileName = findViewById(R.id.newFileName); newFileContent = findViewById(R.id.newFileContent); newFileBranchName = findViewById(R.id.newFileBranchName); newFileCommitMessage = findViewById(R.id.newFileCommitMessage); - TextView branchNameId = findViewById(R.id.branchNameId); - TextView branchNameHintText = findViewById(R.id.branchNameHintText); TextView toolbarTitle = findViewById(R.id.toolbarTitle); - TextView fileNameHint = findViewById(R.id.fileNameHint); newFileName.requestFocus(); assert imm != null; @@ -97,9 +96,19 @@ public class CreateFileActivity extends BaseActivity { newFileCreate = findViewById(R.id.newFileCreate); + newFileContent.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", 1) == 1) { - fileNameHint.setVisibility(View.GONE); fileAction = getIntent().getIntExtra("fileAction", 1); filePath = getIntent().getStringExtra("filePath"); @@ -120,7 +129,6 @@ public class CreateFileActivity extends BaseActivity { if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", 2) == 2) { - fileNameHint.setVisibility(View.GONE); fileAction = getIntent().getIntExtra("fileAction", 2); filePath = getIntent().getStringExtra("filePath"); @@ -141,33 +149,7 @@ public class CreateFileActivity extends BaseActivity { closeActivity.setOnClickListener(onClickListener); newFileBranchesSpinner = findViewById(R.id.newFileBranchesSpinner); - getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid); - - newFileBranchesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() - { - public void onItemSelected(AdapterView arg0, - View arg1, int arg2, long arg3) - { - Branches bModelValue = (Branches) newFileBranchesSpinner.getSelectedItem(); - - if(bModelValue.toString().equals("No branch")) { - newFileBranchName.setEnabled(true); - newFileBranchName.setVisibility(View.VISIBLE); - branchNameId.setVisibility(View.VISIBLE); - branchNameHintText.setVisibility(View.VISIBLE); - } - else { - newFileBranchName.setEnabled(false); - newFileBranchName.setVisibility(View.GONE); - branchNameId.setVisibility(View.GONE); - branchNameHintText.setVisibility(View.GONE); - newFileBranchName.setText(""); - } - - } - - public void onNothingSelected(AdapterView arg0) {} - }); + getBranches(instanceToken, repoOwner, repoName, loginUid); disableProcessButton(); @@ -182,54 +164,43 @@ public class CreateFileActivity extends BaseActivity { } - private View.OnClickListener createFileListener = v -> processNewFile(); + private final View.OnClickListener createFileListener = v -> processNewFile(); private void processNewFile() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - 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]; String newFileName_ = newFileName.getText().toString(); String newFileContent_ = newFileContent.getText().toString(); String newFileBranchName_ = newFileBranchName.getText().toString(); String newFileCommitMessage_ = newFileCommitMessage.getText().toString(); - Branches currentBranch = (Branches) newFileBranchesSpinner.getSelectedItem(); - if(!connToInternet) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) { Toasty.error(ctx, getString(R.string.newFileRequiredFields)); return; - } - if(currentBranch.toString().equals("No branch")) { + if(selectedBranch.equals("No branch")) { if(newFileBranchName_.equals("")) { + Toasty.error(ctx, getString(R.string.newFileRequiredFieldNewBranchName)); return; } else { + if(!appUtil.checkStringsWithDash(newFileBranchName_)) { Toasty.error(ctx, getString(R.string.newFileInvalidBranchName)); return; - } } @@ -238,7 +209,6 @@ public class CreateFileActivity extends BaseActivity { if(appUtil.charactersLength(newFileCommitMessage_) > 255) { Toasty.warning(ctx, getString(R.string.newFileCommitMessageError)); - } else { @@ -246,37 +216,38 @@ public class CreateFileActivity extends BaseActivity { if(fileAction == 1) { - deleteFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, filePath, - newFileBranchName_, newFileCommitMessage_, currentBranch.toString(), fileSha); + deleteFile(Authorization.get(ctx), repoOwner, repoName, filePath, + newFileBranchName_, newFileCommitMessage_, selectedBranch, fileSha); } else if(fileAction == 2) { - editFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, filePath, - appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString(), fileSha); + editFile(Authorization.get(ctx), repoOwner, repoName, filePath, + appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, selectedBranch, fileSha); } else { - createNewFile(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newFileName_, - appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, currentBranch.toString()); + createNewFile(Authorization.get(ctx), repoOwner, repoName, newFileName_, + appUtil.encodeBase64(newFileContent_), newFileBranchName_, newFileCommitMessage_, selectedBranch); } } } - private void createNewFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch) { + private void createNewFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch) { NewFile createNewFileJsonStr; if(currentBranch.equals("No branch")) { + createNewFileJsonStr = new NewFile("", fileContent, fileCommitMessage, fileBranchName); } else { + createNewFileJsonStr = new NewFile(currentBranch, fileContent, fileCommitMessage, ""); } Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr); call.enqueue(new Callback() { @@ -289,7 +260,6 @@ public class CreateFileActivity extends BaseActivity { enableProcessButton(); Toasty.success(ctx, getString(R.string.newFileSuccessMessage)); finish(); - } else if(response.code() == 401) { @@ -298,21 +268,20 @@ public class CreateFileActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { if(response.code() == 404) { + enableProcessButton(); Toasty.warning(ctx, getString(R.string.apiNotFound)); } else { + enableProcessButton(); Toasty.error(ctx, getString(R.string.orgCreatedError)); } - } - } @Override @@ -325,10 +294,11 @@ public class CreateFileActivity extends BaseActivity { } - private void deleteFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) { + private void deleteFile(final String token, String repoOwner, String repoName, String fileName, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) { String branchName; DeleteFile deleteFileJsonStr; + if(currentBranch.equals("No branch")) { branchName = fileBranchName; @@ -341,8 +311,7 @@ public class CreateFileActivity extends BaseActivity { } Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .deleteFile(token, repoOwner, repoName, fileName, deleteFileJsonStr); call.enqueue(new Callback() { @@ -358,7 +327,6 @@ public class CreateFileActivity extends BaseActivity { getIntent().removeExtra("fileSha"); getIntent().removeExtra("fileContents"); finish(); - } else if(response.code() == 401) { @@ -367,7 +335,6 @@ public class CreateFileActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { @@ -381,9 +348,7 @@ public class CreateFileActivity extends BaseActivity { enableProcessButton(); Toasty.info(ctx, getString(R.string.genericError)); } - } - } @Override @@ -396,10 +361,11 @@ public class CreateFileActivity extends BaseActivity { } - private void editFile(final String instanceUrl, final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) { + private void editFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileBranchName, String fileCommitMessage, String currentBranch, String fileSha) { String branchName; EditFile editFileJsonStr; + if(currentBranch.equals("No branch")) { branchName = fileBranchName; @@ -412,8 +378,7 @@ public class CreateFileActivity extends BaseActivity { } Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .editFile(token, repoOwner, repoName, fileName, editFileJsonStr); call.enqueue(new Callback() { @@ -428,9 +393,8 @@ public class CreateFileActivity extends BaseActivity { getIntent().removeExtra("filePath"); getIntent().removeExtra("fileSha"); getIntent().removeExtra("fileContents"); - tinyDb.putBoolean("fileModified", true); + tinyDB.putBoolean("fileModified", true); finish(); - } else if(response.code() == 401) { @@ -439,7 +403,6 @@ public class CreateFileActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { @@ -453,9 +416,7 @@ public class CreateFileActivity extends BaseActivity { enableProcessButton(); Toasty.info(ctx, getString(R.string.genericError)); } - } - } @Override @@ -468,12 +429,11 @@ public class CreateFileActivity extends BaseActivity { } - private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { + private void getBranches(String instanceToken, String repoOwner, String repoName, String loginUid) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(ctx) + .getBranches(Authorization.get(ctx), repoOwner, repoName); call.enqueue(new Callback>() { @@ -481,37 +441,53 @@ public class CreateFileActivity extends BaseActivity { public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { if(response.isSuccessful()) { + if(response.code() == 200) { List branchesList_ = response.body(); branchesList.add(new Branches("No branch")); assert branchesList_ != null; + if(branchesList_.size() > 0) { + for (int i = 0; i < branchesList_.size(); i++) { - Branches data = new Branches( - branchesList_.get(i).getName() - ); + Branches data = new Branches(branchesList_.get(i).getName()); branchesList.add(data); - } } ArrayAdapter adapter = new ArrayAdapter<>(CreateFileActivity.this, - R.layout.spinner_item, branchesList); + R.layout.list_spinner_items, branchesList); - adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); newFileBranchesSpinner.setAdapter(adapter); enableProcessButton(); + newFileBranchesSpinner.setOnItemClickListener ((parent, view, position, id) -> { + + selectedBranch = branchesList.get(position).getName(); + + if(selectedBranch.equals("No branch")) { + + newFileBranchName.setEnabled(true); + newFileBranchName.setVisibility(View.VISIBLE); + } + else { + + newFileBranchName.setEnabled(false); + newFileBranchName.setVisibility(View.GONE); + newFileBranchName.setText(""); + } + + }); } } - } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); } }); @@ -519,6 +495,7 @@ public class CreateFileActivity extends BaseActivity { } private void initCloseListener() { + onClickListener = view -> finish(); } diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java index 52e060b1..6b2bb2f2 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java @@ -1,5 +1,6 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.app.Dialog; import android.content.Context; @@ -7,6 +8,7 @@ import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; @@ -49,9 +51,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis private CustomLabelsSelectionDialogBinding labelsBinding; private CustomAssigneesSelectionDialogBinding assigneesBinding; private View.OnClickListener onClickListener; - final Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private Dialog dialogLabels; private Dialog dialogAssignees; @@ -59,9 +58,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis private String assigneesSetter; private int milestoneId; - private String instanceUrl; private String loginUid; - private String instanceToken; private String repoOwner; private String repoName; @@ -79,12 +76,11 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis return R.layout.activity_create_issue; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); @@ -94,17 +90,14 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - final String loginFullName = tinyDb.getString("userFullname"); - String repoFullName = tinyDb.getString("repoFullName"); + loginUid = tinyDB.getString("loginUid"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); repoOwner = parts[0]; repoName = parts[1]; - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); // require gitea 1.12 or higher - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } @@ -113,6 +106,17 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis assert imm != null; imm.showSoftInput(viewBinding.newIssueTitle, InputMethodManager.SHOW_IMPLICIT); + viewBinding.newIssueDescription.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + labelsAdapter = new LabelsListAdapter(labelsList, CreateIssueActivity.this, labelsIds); assigneesAdapter = new AssigneesListAdapter(ctx, assigneesList, CreateIssueActivity.this, assigneesListData); @@ -123,17 +127,13 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis viewBinding.newIssueLabels.setOnClickListener(this); viewBinding.newIssueDueDate.setOnClickListener(this); - getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); + getMilestones(repoOwner, repoName, resultLimit); disableProcessButton(); - viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> - showLabels() - ); + viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> showLabels()); - viewBinding.newIssueAssigneesList.setOnClickListener(newIssueAssigneesList -> - showAssignees() - ); + viewBinding.newIssueAssigneesList.setOnClickListener(newIssueAssigneesList -> showAssignees()); if(!connToInternet) { @@ -181,11 +181,10 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis View view = assigneesBinding.getRoot(); dialogAssignees.setContentView(view); - assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> - dialogAssignees.dismiss() - ); + assigneesBinding.cancel.setOnClickListener(assigneesBinding_ -> dialogAssignees.dismiss()); - AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); + dialogAssignees.show(); + AssigneesActions.getRepositoryAssignees(ctx, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); } private void showLabels() { @@ -202,11 +201,10 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis View view = labelsBinding.getRoot(); dialogLabels.setContentView(view); - labelsBinding.cancel.setOnClickListener(labelsBinding_ -> - dialogLabels.dismiss() - ); + labelsBinding.cancel.setOnClickListener(labelsBinding_ -> dialogLabels.dismiss()); - LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); + dialogLabels.show(); + LabelsActions.getRepositoryLabels(ctx, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); } private void processNewIssue() { @@ -221,7 +219,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if (newIssueTitleForm.equals("")) { @@ -240,20 +237,18 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis } disableProcessButton(); - createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, milestoneId, newIssueTitleForm); - + createNewIssueFunc(repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, milestoneId, newIssueTitleForm); } - private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm) { + private void createNewIssueFunc(String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm) { CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, assigneesListData, labelsIds); Call call3; call3 = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .createNewIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createNewIssueJson); + .getApiInterface(ctx) + .createNewIssue(Authorization.get(ctx), repoOwner, repoName, createNewIssueJson); call3.enqueue(new Callback() { @@ -262,7 +257,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis if(response2.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); tinyDb.putBoolean("resumeIssues", true); Toasty.success(ctx, getString(R.string.issueCreated)); @@ -300,13 +295,12 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis onClickListener = view -> finish(); } - private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) { + private void getMilestones(String repoOwner, String repoName, int resultLimit) { String msState = "open"; Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); + .getApiInterface(ctx) + .getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState); call.enqueue(new Callback>() { @@ -314,13 +308,16 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { if(response.isSuccessful()) { + if(response.code() == 200) { List milestonesList_ = response.body(); milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone))); assert milestonesList_ != null; + if(milestonesList_.size() > 0) { + for (int i = 0; i < milestonesList_.size(); i++) { //Don't translate "open" is a enum @@ -331,7 +328,6 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis ); milestonesList.add(data); } - } } @@ -375,9 +371,9 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis datePickerDialog.show(); } else if(v == viewBinding.createNewIssueButton) { + processNewIssue(); } - } private void disableProcessButton() { diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateLabelActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateLabelActivity.java index 9a75f8e1..cb88c139 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateLabelActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateLabelActivity.java @@ -10,11 +10,9 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import com.pes.androidmaterialcolorpickerdialog.ColorPicker; -import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; @@ -25,6 +23,7 @@ import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.CreateLabel; import org.mian.gitnex.models.Labels; import org.mian.gitnex.viewmodels.LabelsViewModel; +import org.mian.gitnex.viewmodels.OrganizationLabelsViewModel; import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; @@ -39,8 +38,7 @@ public class CreateLabelActivity extends BaseActivity { private TextView colorPicker; private EditText labelName; private Button createLabelButton; - final Context ctx = this; - private Context appCtx; + private TinyDB tinyDB; @Override protected int getLayoutResourceId(){ @@ -51,25 +49,20 @@ public class CreateLabelActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - final TinyDB tinyDb = new TinyDB(appCtx); - String repoFullName = tinyDb.getString("repoFullName"); + tinyDB = TinyDB.getInstance(appCtx); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("delete")) { - deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid); + deleteLabel(repoOwner, repoName, Integer.parseInt(Objects.requireNonNull(getIntent().getStringExtra("labelId")))); finish(); return; - } boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -87,22 +80,14 @@ public class CreateLabelActivity extends BaseActivity { initCloseListener(); closeActivity.setOnClickListener(onClickListener); - colorPicker.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - cp.show(); - } - }); + colorPicker.setOnClickListener(v -> cp.show()); - cp.setCallback(new ColorPickerCallback() { - @Override - public void onColorChosen(@ColorInt int color) { + cp.setCallback(color -> { - //Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color))); - colorPicker.setBackgroundColor(color); - tinyDb.putString("labelColor", String.format("#%06X", (0xFFFFFF & color))); - cp.dismiss(); - - } + //Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color))); + colorPicker.setBackgroundColor(color); + tinyDB.putString("labelColor", String.format("#%06X", (0xFFFFFF & color))); + cp.dismiss(); }); if(getIntent().getStringExtra("labelAction") != null && Objects.requireNonNull(getIntent().getStringExtra("labelAction")).equals("edit")) { @@ -110,7 +95,7 @@ public class CreateLabelActivity extends BaseActivity { labelName.setText(getIntent().getStringExtra("labelTitle")); int labelColor_ = Color.parseColor("#" + getIntent().getStringExtra("labelColor")); colorPicker.setBackgroundColor(labelColor_); - tinyDb.putString("labelColorDefault", "#" + getIntent().getStringExtra("labelColor")); + tinyDB.putString("labelColorDefault", "#" + getIntent().getStringExtra("labelColor")); TextView toolbar_title = findViewById(R.id.toolbar_title); toolbar_title.setText(getResources().getString(R.string.pageTitleLabelUpdate)); @@ -131,57 +116,52 @@ public class CreateLabelActivity extends BaseActivity { } - private View.OnClickListener createLabelListener = v -> processCreateLabel(); + private final View.OnClickListener createLabelListener = v -> processCreateLabel(); - private View.OnClickListener updateLabelListener = v -> processUpdateLabel(); + private final View.OnClickListener updateLabelListener = v -> processUpdateLabel(); private void processUpdateLabel() { - final TinyDB tinyDb = new TinyDB(appCtx); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - String repoFullName = tinyDb.getString("repoFullName"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); String updateLabelName = labelName.getText().toString(); String updateLabelColor; - if(tinyDb.getString("labelColor").isEmpty()) { - updateLabelColor = tinyDb.getString("labelColorDefault"); + if(tinyDB.getString("labelColor").isEmpty()) { + + updateLabelColor = tinyDB.getString("labelColorDefault"); } else { - updateLabelColor = tinyDb.getString("labelColor"); + + updateLabelColor = tinyDB.getString("labelColor"); } if(!connToInternet) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(updateLabelName.equals("")) { Toasty.error(ctx, getString(R.string.labelEmptyError)); return; - } if(!appUtil.checkStrings(updateLabelName)) { Toasty.error(ctx, getString(R.string.labelNameError)); return; - } disableProcessButton(); - patchLabel(instanceUrl, instanceToken, repoOwner, repoName, updateLabelName, updateLabelColor, Integer.parseInt( - Objects.requireNonNull(getIntent().getStringExtra("labelId"))), loginUid); + patchLabel(repoOwner, repoName, updateLabelName, updateLabelColor, Integer.parseInt( + Objects.requireNonNull(getIntent().getStringExtra("labelId")))); } @@ -189,61 +169,60 @@ public class CreateLabelActivity extends BaseActivity { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - TinyDB tinyDb = new TinyDB(appCtx); - String repoFullName = tinyDb.getString("repoFullName"); + + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); String newLabelName = labelName.getText().toString(); String newLabelColor; - if(tinyDb.getString("labelColor").isEmpty()) { + + if(tinyDB.getString("labelColor").isEmpty()) { + newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(ctx, R.color.releasePre))); } else { - newLabelColor = tinyDb.getString("labelColor"); + + newLabelColor = tinyDB.getString("labelColor"); } if(!connToInternet) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(newLabelName.equals("")) { Toasty.error(ctx, getString(R.string.labelEmptyError)); return; - } if(!appUtil.checkStrings(newLabelName)) { Toasty.error(ctx, getString(R.string.labelNameError)); return; - } disableProcessButton(); - createNewLabel(instanceUrl, instanceToken, repoOwner, repoName, newLabelName, newLabelColor, loginUid); - + createNewLabel(repoOwner, repoName, newLabelName, newLabelColor); } - private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) { + private void createNewLabel(String repoOwner, String repoName, String newLabelName, String newLabelColor) { CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor); - final TinyDB tinyDb = new TinyDB(appCtx); Call call; - call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .createLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, createLabelFunc); + if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) { + + call = RetrofitClient.getApiInterface(ctx).createOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), createLabelFunc); + } + else { + + call = RetrofitClient.getApiInterface(ctx).createLabel(Authorization.get(ctx), repoOwner, repoName, createLabelFunc); + } call.enqueue(new Callback() { @@ -253,10 +232,9 @@ public class CreateLabelActivity extends BaseActivity { if(response.code() == 201) { Toasty.success(ctx, getString(R.string.labelCreated)); - tinyDb.putString("labelColor", ""); - tinyDb.putBoolean("labelsRefresh", true); + tinyDB.putString("labelColor", ""); + tinyDB.putBoolean("labelsRefresh", true); finish(); - } else if(response.code() == 401) { @@ -265,22 +243,19 @@ public class CreateLabelActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { enableProcessButton(); - tinyDb.putString("labelColor", ""); + tinyDB.putString("labelColor", ""); Toasty.error(ctx, getString(R.string.labelGeneralError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - tinyDb.putString("labelColor", ""); + tinyDB.putString("labelColor", ""); Log.e("onFailure", t.toString()); enableProcessButton(); } @@ -288,17 +263,20 @@ public class CreateLabelActivity extends BaseActivity { } - private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) { + private void patchLabel(String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId) { CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor); - final TinyDB tinyDb = new TinyDB(appCtx); Call call; - call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .patchLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc); + if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) { + + call = RetrofitClient.getApiInterface(ctx).patchOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), labelId, createLabelFunc); + } + else { + + call = RetrofitClient.getApiInterface(appCtx).patchLabel(Authorization.get(ctx), repoOwner, repoName, labelId, createLabelFunc); + } call.enqueue(new Callback() { @@ -306,18 +284,19 @@ public class CreateLabelActivity extends BaseActivity { public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { + if(response.code() == 200) { Toasty.success(ctx, getString(R.string.labelUpdated)); - tinyDb.putString("labelColor", ""); - tinyDb.putBoolean("labelsRefresh", true); - tinyDb.putString("labelColorDefault", ""); + tinyDB.putString("labelColor", ""); + tinyDB.putBoolean("labelsRefresh", true); + tinyDB.putString("labelColorDefault", ""); getIntent().removeExtra("labelAction"); getIntent().removeExtra("labelId"); getIntent().removeExtra("labelTitle"); getIntent().removeExtra("labelColor"); + getIntent().removeExtra("type"); finish(); - } } else if(response.code() == 401) { @@ -327,24 +306,21 @@ public class CreateLabelActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { enableProcessButton(); - tinyDb.putString("labelColor", ""); - tinyDb.putString("labelColorDefault", ""); + tinyDB.putString("labelColor", ""); + tinyDB.putString("labelColorDefault", ""); Toasty.error(ctx, getString(R.string.labelGeneralError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - tinyDb.putString("labelColor", ""); - tinyDb.putString("labelColorDefault", ""); + tinyDB.putString("labelColor", ""); + tinyDB.putString("labelColorDefault", ""); Log.e("onFailure", t.toString()); enableProcessButton(); } @@ -353,26 +329,30 @@ public class CreateLabelActivity extends BaseActivity { } private void initCloseListener() { - onClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - getIntent().removeExtra("labelAction"); - getIntent().removeExtra("labelId"); - getIntent().removeExtra("labelTitle"); - getIntent().removeExtra("labelColor"); - finish(); - } + + onClickListener = view -> { + + getIntent().removeExtra("labelAction"); + getIntent().removeExtra("labelId"); + getIntent().removeExtra("labelTitle"); + getIntent().removeExtra("labelColor"); + getIntent().removeExtra("type"); + finish(); }; } - private void deleteLabel(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, int labelId, String loginUid) { + private void deleteLabel(final String repoOwner, final String repoName, int labelId) { Call call; - call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .deleteLabel(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, labelId); + if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) { + + call = RetrofitClient.getApiInterface(appCtx).deleteOrganizationLabel(Authorization.get(ctx), getIntent().getStringExtra("orgName"), labelId); + } + else { + + call = RetrofitClient.getApiInterface(appCtx).deleteLabel(Authorization.get(ctx), repoOwner, repoName, labelId); + } call.enqueue(new Callback() { @@ -380,13 +360,21 @@ public class CreateLabelActivity extends BaseActivity { public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { + if(response.code() == 204) { Toasty.success(ctx, getString(R.string.labelDeleteText)); - LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName, ctx); + if(getIntent().getStringExtra("type") != null && Objects.requireNonNull(getIntent().getStringExtra("type")).equals("org")) { + + OrganizationLabelsViewModel.loadOrgLabelsList(Authorization.get(ctx), getIntent().getStringExtra("orgName"), ctx, null, null); + } + else { + + LabelsViewModel.loadLabelsList(Authorization.get(ctx), repoOwner, repoName, ctx); + } getIntent().removeExtra("labelAction"); getIntent().removeExtra("labelId"); - + getIntent().removeExtra("type"); } } else if(response.code() == 401) { @@ -395,14 +383,11 @@ public class CreateLabelActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { Toasty.error(ctx, getString(R.string.labelDeleteErrorText)); - } - } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateMilestoneActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateMilestoneActivity.java index fc94bfdc..3c910bce 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateMilestoneActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateMilestoneActivity.java @@ -1,13 +1,14 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.content.Context; import android.os.Bundle; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; -import android.widget.DatePicker; import android.widget.EditText; import android.widget.ImageView; import androidx.annotation.NonNull; @@ -35,19 +36,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic private EditText milestoneTitle; private EditText milestoneDescription; private Button createNewMilestoneButton; - final Context ctx = this; - private Context appCtx; @Override protected int getLayoutResourceId(){ return R.layout.activity_new_milestone; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -63,6 +62,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic assert imm != null; imm.showSoftInput(milestoneTitle, InputMethodManager.SHOW_IMPLICIT); + milestoneDescription.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + initCloseListener(); closeActivity.setOnClickListener(onClickListener); milestoneDueDate.setOnClickListener(this); @@ -78,21 +88,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic } - private View.OnClickListener createMilestoneListener = v -> processNewMilestone(); + private final View.OnClickListener createMilestoneListener = v -> processNewMilestone(); private void processNewMilestone() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - //String appLocale = tinyDb.getString("locale"); String newMilestoneTitle = milestoneTitle.getText().toString(); String newMilestoneDescription = milestoneDescription.getText().toString(); @@ -102,26 +108,25 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(newMilestoneTitle.equals("")) { Toasty.error(ctx, getString(R.string.milestoneNameErrorEmpty)); return; - } if(!newMilestoneDescription.equals("")) { + if (appUtil.charactersLength(newMilestoneDescription) > 255) { Toasty.warning(ctx, getString(R.string.milestoneDescError)); return; - } } String finalMilestoneDueDate = null; + if(!newMilestoneDueDate.isEmpty()) { finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate))); @@ -134,19 +139,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic } disableProcessButton(); - createNewMilestone(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate); - + createNewMilestone(Authorization.get(ctx), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate); } - private void createNewMilestone(final String instanceUrl, final String token, String repoOwner, String repoName, String newMilestoneTitle, String newMilestoneDescription, String newMilestoneDueDate) { + private void createNewMilestone(final String token, String repoOwner, String repoName, String newMilestoneTitle, String newMilestoneDescription, String newMilestoneDueDate) { Milestones createMilestone = new Milestones(newMilestoneDescription, newMilestoneTitle, newMilestoneDueDate); Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(appCtx) .createMilestone(token, repoOwner, repoName, createMilestone); call.enqueue(new Callback() { @@ -155,14 +158,14 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.isSuccessful()) { + if(response.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); tinyDb.putBoolean("milestoneCreated", true); Toasty.success(ctx, getString(R.string.milestoneCreated)); enableProcessButton(); finish(); - } } else if(response.code() == 401) { @@ -172,19 +175,17 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { enableProcessButton(); Toasty.error(ctx, getString(R.string.milestoneCreatedError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); enableProcessButton(); } @@ -203,16 +204,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic 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) { - - milestoneDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)); - - } - }, mYear, mMonth, mDay); + (view, year, monthOfYear, dayOfMonth) -> milestoneDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay); datePickerDialog.show(); } diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateNewUserActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateNewUserActivity.java index 49f69ad2..9c056743 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateNewUserActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateNewUserActivity.java @@ -33,8 +33,6 @@ public class CreateNewUserActivity extends BaseActivity { private EditText userEmail; private EditText userPassword; private Button createUserButton; - final Context ctx = this; - private Context appCtx; @Override protected int getLayoutResourceId(){ @@ -45,7 +43,6 @@ public class CreateNewUserActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -73,17 +70,13 @@ public class CreateNewUserActivity extends BaseActivity { createUserButton.setOnClickListener(createNewUserListener); } - } private void processCreateNewUser() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - 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"); + TinyDB tinyDb = TinyDB.getInstance(appCtx); String newFullName = fullName.getText().toString().trim(); String newUserName = userUserName.getText().toString().trim(); @@ -94,51 +87,44 @@ public class CreateNewUserActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) { Toasty.error(ctx, getString(R.string.emptyFields)); return; - } if(!appUtil.checkStrings(newFullName)) { Toasty.error(ctx, getString(R.string.userInvalidFullName)); return; - } if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) { Toasty.error(ctx, getString(R.string.userInvalidUserName)); return; - } if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { Toasty.error(ctx, getString(R.string.userInvalidEmail)); return; - } disableProcessButton(); - createNewUser(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword); - + createNewUser(Authorization.get(ctx), newFullName, newUserName, newUserEmail, newUserPassword); } - private void createNewUser(final String instanceUrl, final String instanceToken, String newFullName, String newUserName, String newUserEmail, String newUserPassword) { + private void createNewUser(final String instanceToken, String newFullName, String newUserName, String newUserEmail, String newUserPassword) { UserInfo createUser = new UserInfo(newUserEmail, newFullName, newUserName, newUserPassword, newUserName, 0, true); Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(appCtx) .createNewUser(instanceToken, createUser); call.enqueue(new Callback() { @@ -151,7 +137,6 @@ public class CreateNewUserActivity extends BaseActivity { Toasty.success(ctx, getString(R.string.userCreatedText)); enableProcessButton(); finish(); - } else if(response.code() == 401) { @@ -160,33 +145,27 @@ public class CreateNewUserActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else if(response.code() == 403) { enableProcessButton(); Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - } else if(response.code() == 404) { enableProcessButton(); Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - } else if(response.code() == 422) { enableProcessButton(); Toasty.warning(ctx, ctx.getString(R.string.userExistsError)); - } else { enableProcessButton(); Toasty.error(ctx, getString(R.string.genericError)); - } - } @Override @@ -199,7 +178,7 @@ public class CreateNewUserActivity extends BaseActivity { } - private View.OnClickListener createNewUserListener = v -> processCreateNewUser(); + private final View.OnClickListener createNewUserListener = v -> processCreateNewUser(); private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateOrganizationActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateOrganizationActivity.java index e3e6b259..dc4ae0db 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateOrganizationActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateOrganizationActivity.java @@ -1,8 +1,10 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; @@ -32,19 +34,17 @@ public class CreateOrganizationActivity extends BaseActivity { private EditText orgName; private EditText orgDesc; - final Context ctx = this; - private Context appCtx; @Override protected int getLayoutResourceId(){ return R.layout.activity_new_organization; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -58,6 +58,17 @@ public class CreateOrganizationActivity extends BaseActivity { assert imm != null; imm.showSoftInput(orgName, InputMethodManager.SHOW_IMPLICIT); + orgDesc.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + initCloseListener(); closeActivity.setOnClickListener(onClickListener); @@ -75,28 +86,17 @@ public class CreateOrganizationActivity extends BaseActivity { } private void initCloseListener() { - onClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - finish(); - } - }; + + onClickListener = view -> finish(); } - private View.OnClickListener createOrgListener = new View.OnClickListener() { - public void onClick(View v) { - processNewOrganization(); - } - }; + private final View.OnClickListener createOrgListener = v -> processNewOrganization(); private void processNewOrganization() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - 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"); + TinyDB tinyDb = TinyDB.getInstance(appCtx); String newOrgName = orgName.getText().toString(); String newOrgDesc = orgDesc.getText().toString(); @@ -105,44 +105,39 @@ public class CreateOrganizationActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(!newOrgDesc.equals("")) { + if (appUtil.charactersLength(newOrgDesc) > 255) { Toasty.warning(ctx, getString(R.string.orgDescError)); return; - } } if(newOrgName.equals("")) { Toasty.error(ctx, getString(R.string.orgNameErrorEmpty)); - } else if(!appUtil.checkStrings(newOrgName)) { Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid)); - } else { disableProcessButton(); - createNewOrganization(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newOrgName, newOrgDesc); - + createNewOrganization(Authorization.get(ctx), newOrgName, newOrgDesc); } } - private void createNewOrganization(final String instanceUrl, final String token, String orgName, String orgDesc) { + private void createNewOrganization(final String token, String orgName, String orgDesc) { UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null); Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(appCtx) .createNewOrganization(token, createOrganization); call.enqueue(new Callback() { @@ -152,12 +147,11 @@ public class CreateOrganizationActivity extends BaseActivity { if(response.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); tinyDb.putBoolean("orgCreated", true); enableProcessButton(); Toasty.success(ctx, getString(R.string.orgCreated)); finish(); - } else if(response.code() == 401) { @@ -166,37 +160,35 @@ public class CreateOrganizationActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else if(response.code() == 409) { enableProcessButton(); Toasty.warning(ctx, getString(R.string.orgExistsError)); - } else if(response.code() == 422) { enableProcessButton(); Toasty.warning(ctx, getString(R.string.orgExistsError)); - } else { if(response.code() == 404) { + enableProcessButton(); Toasty.warning(ctx, getString(R.string.apiNotFound)); } else { + enableProcessButton(); Toasty.error(ctx, getString(R.string.orgCreatedError)); } - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); enableProcessButton(); } 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 0809b0ba..ed13ab48 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java @@ -1,12 +1,13 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.app.Dialog; -import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ImageView; @@ -20,7 +21,6 @@ import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.StaticGlobalVariables; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import org.mian.gitnex.models.Branches; @@ -41,9 +41,6 @@ import retrofit2.Callback; public class CreatePullRequestActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener { private View.OnClickListener onClickListener; - private Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; private ActivityCreatePrBinding viewBinding; private CustomLabelsSelectionDialogBinding labelsBinding; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; @@ -53,7 +50,6 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis private List assignees = new ArrayList<>(); private int milestoneId; - private String instanceUrl; private String loginUid; private String instanceToken; private String repoOwner; @@ -73,30 +69,40 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis return R.layout.activity_create_pr; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); setContentView(view); - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); + loginUid = tinyDB.getString("loginUid"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); repoOwner = parts[0]; repoName = parts[1]; - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + instanceToken = "token " + tinyDB.getString(loginUid + "-token"); // require gitea 1.12 or higher - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } + viewBinding.prBody.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + labelsAdapter = new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds); ImageView closeActivity = findViewById(R.id.close); @@ -110,16 +116,12 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis disableProcessButton(); - getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); - getBranches(instanceUrl, instanceToken, repoOwner, repoName, loginUid); + getMilestones(repoOwner, repoName, resultLimit); + getBranches(repoOwner, repoName); - viewBinding.prLabels.setOnClickListener(prLabels -> - showLabels() - ); + viewBinding.prLabels.setOnClickListener(prLabels -> showLabels()); - viewBinding.createPr.setOnClickListener(createPr -> - processPullRequest() - ); + viewBinding.createPr.setOnClickListener(createPr -> processPullRequest()); } private void processPullRequest() { @@ -133,13 +135,16 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis assignees.add(""); if (labelsIds.size() == 0) { + labelsIds.add(0); } if (dueDate.matches("")) { + dueDate = null; } else { + dueDate = AppUtil.customDateCombine(AppUtil.customDateFormat(dueDate)); } @@ -160,9 +165,9 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis Toasty.error(ctx, getString(R.string.sameBranchesError)); } else { + createPullRequest(prTitle, prDescription, mergeInto, pullFrom, milestoneId, dueDate, assignees); } - //Log.e("processPullRequest", String.valueOf(milestoneId)); } private void createPullRequest(String prTitle, String prDescription, String mergeInto, String pullFrom, int milestoneId, String dueDate, List assignees) { @@ -170,8 +175,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds); Call transferCall = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(appCtx) .createPullRequest(instanceToken, repoOwner, repoName, createPullRequest); transferCall.enqueue(new Callback() { @@ -201,7 +205,6 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis enableProcessButton(); Toasty.error(ctx, getString(R.string.genericError)); } - } @Override @@ -231,6 +234,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis dialogLabels = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); if (dialogLabels.getWindow() != null) { + dialogLabels.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } @@ -239,19 +243,17 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis View view = labelsBinding.getRoot(); dialogLabels.setContentView(view); - labelsBinding.cancel.setOnClickListener(editProperties -> - dialogLabels.dismiss() - ); + labelsBinding.cancel.setOnClickListener(editProperties -> dialogLabels.dismiss()); - LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); + dialogLabels.show(); + LabelsActions.getRepositoryLabels(ctx, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); } - private void getBranches(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { + private void getBranches(String repoOwner, String repoName) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getBranches(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); + .getApiInterface(ctx) + .getBranches(Authorization.get(ctx), repoOwner, repoName); call.enqueue(new Callback>() { @@ -259,19 +261,18 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { if(response.isSuccessful()) { + if(response.code() == 200) { List branchesList_ = response.body(); - assert branchesList_ != null; + if(branchesList_.size() > 0) { + for (int i = 0; i < branchesList_.size(); i++) { - Branches data = new Branches( - branchesList_.get(i).getName() - ); + Branches data = new Branches(branchesList_.get(i).getName()); branchesList.add(data); - } } @@ -296,13 +297,12 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis } - private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) { + private void getMilestones(String repoOwner, String repoName, int resultLimit) { String msState = "open"; Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); + .getApiInterface(appCtx) + .getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState); call.enqueue(new Callback>() { @@ -315,7 +315,9 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis milestonesList.add(new Milestones(0,getString(R.string.issueCreatedNoMilestone))); assert milestonesList_ != null; + if(milestonesList_.size() > 0) { + for (int i = 0; i < milestonesList_.size(); i++) { //Don't translate "open" is a enum @@ -326,7 +328,6 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis ); milestonesList.add(data); } - } } diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateReleaseActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateReleaseActivity.java index 99cba7d3..7125d0ca 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateReleaseActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateReleaseActivity.java @@ -1,24 +1,24 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; -import android.widget.Spinner; import androidx.annotation.NonNull; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Releases; @@ -36,14 +36,16 @@ public class CreateReleaseActivity extends BaseActivity { private View.OnClickListener onClickListener; public ImageView closeActivity; private EditText releaseTagName; - private Spinner releaseBranch; + private AutoCompleteTextView releaseBranch; private EditText releaseTitle; private EditText releaseContent; private CheckBox releaseType; private CheckBox releaseDraft; private Button createNewRelease; - final Context ctx = this; - private Context appCtx; + private String selectedBranch; + + private String repoOwner; + private String repoName; List branchesList = new ArrayList<>(); @@ -52,24 +54,20 @@ public class CreateReleaseActivity extends BaseActivity { return R.layout.activity_create_release; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); 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"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - String repoFullName = tinyDb.getString("repoFullName"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; + repoOwner = parts[0]; + repoName = parts[1]; closeActivity = findViewById(R.id.close); releaseTagName = findViewById(R.id.releaseTagName); @@ -78,26 +76,26 @@ public class CreateReleaseActivity extends BaseActivity { releaseType = findViewById(R.id.releaseType); releaseDraft = findViewById(R.id.releaseDraft); - releaseTagName.requestFocus(); + releaseTitle.requestFocus(); assert imm != null; - imm.showSoftInput(releaseTagName, InputMethodManager.SHOW_IMPLICIT); + imm.showSoftInput(releaseTitle, InputMethodManager.SHOW_IMPLICIT); + + releaseContent.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); initCloseListener(); closeActivity.setOnClickListener(onClickListener); releaseBranch = findViewById(R.id.releaseBranch); - getBranches(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); - releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - Branches branch = (Branches) parent.getSelectedItem(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }); + getBranches(Authorization.get(ctx), repoOwner, repoName); createNewRelease = findViewById(R.id.createNewRelease); disableProcessButton(); @@ -113,25 +111,16 @@ public class CreateReleaseActivity extends BaseActivity { } - private View.OnClickListener createReleaseListener = v -> processNewRelease(); + private final View.OnClickListener createReleaseListener = v -> processNewRelease(); private void processNewRelease() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - 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]; - String newReleaseTagName = releaseTagName.getText().toString(); String newReleaseTitle = releaseTitle.getText().toString(); String newReleaseContent = releaseContent.getText().toString(); - String newReleaseBranch = releaseBranch.getSelectedItem().toString(); + String checkBranch = selectedBranch; boolean newReleaseType = releaseType.isChecked(); boolean newReleaseDraft = releaseDraft.isChecked(); @@ -139,37 +128,38 @@ public class CreateReleaseActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } + if(newReleaseTitle.equals("")) { + + Toasty.error(ctx, getString(R.string.titleErrorEmpty)); + return; + } + if(newReleaseTagName.equals("")) { Toasty.error(ctx, getString(R.string.tagNameErrorEmpty)); return; - } - if(newReleaseTitle.equals("")) { + if(checkBranch == null) { - Toasty.error(ctx, getString(R.string.titleErrorEmpty)); - return; - - } + Toasty.error(ctx, getString(R.string.selectBranchError)); + return; + } disableProcessButton(); - createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft); - + createNewReleaseFunc(Authorization.get(ctx), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, selectedBranch, newReleaseType, newReleaseDraft); } - private void createNewReleaseFunc(final String instanceUrl, final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String newReleaseBranch, boolean newReleaseType, boolean newReleaseDraft) { + private void createNewReleaseFunc(final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String selectedBranch, boolean newReleaseType, boolean newReleaseDraft) { - Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, newReleaseBranch); + Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, selectedBranch); Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .createNewRelease(token, repoOwner, repoName, createReleaseJson); call.enqueue(new Callback() { @@ -179,12 +169,10 @@ public class CreateReleaseActivity extends BaseActivity { if (response.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); - tinyDb.putBoolean("updateReleases", true); + tinyDB.putBoolean("updateReleases", true); Toasty.success(ctx, getString(R.string.releaseCreatedText)); enableProcessButton(); finish(); - } else if(response.code() == 401) { @@ -193,31 +181,27 @@ public class CreateReleaseActivity extends BaseActivity { ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else if(response.code() == 403) { enableProcessButton(); Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - } else if(response.code() == 404) { enableProcessButton(); Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - } else { enableProcessButton(); Toasty.error(ctx, ctx.getString(R.string.genericError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); enableProcessButton(); } @@ -225,11 +209,10 @@ public class CreateReleaseActivity extends BaseActivity { } - private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) { + private void getBranches(String instanceToken, final String repoOwner, final String repoName) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getBranches(instanceToken, repoOwner, repoName); call.enqueue(new Callback>() { @@ -238,29 +221,27 @@ public class CreateReleaseActivity extends BaseActivity { public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { if(response.isSuccessful()) { + if(response.code() == 200) { List branchesList_ = response.body(); assert branchesList_ != null; if(branchesList_.size() > 0) { - for (int i = 0; i < branchesList_.size(); i++) { - Branches data = new Branches( - branchesList_.get(i).getName() - ); - branchesList.add(data); - - } + branchesList.addAll(branchesList_); } - ArrayAdapter adapter = new ArrayAdapter<>(CreateReleaseActivity.this, - R.layout.spinner_item, branchesList); + ArrayAdapter adapter = new ArrayAdapter<>(CreateReleaseActivity.this, + R.layout.list_spinner_items, branchesList); - adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); releaseBranch.setAdapter(adapter); enableProcessButton(); + releaseBranch.setOnItemClickListener ((parent, view, position, id) -> + + selectedBranch = branchesList.get(position).getName() + ); } } else if(response.code() == 401) { @@ -269,13 +250,13 @@ public class CreateReleaseActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); } }); @@ -283,12 +264,8 @@ public class CreateReleaseActivity extends BaseActivity { } private void initCloseListener() { - onClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - finish(); - } - }; + + onClickListener = view -> finish(); } private void disableProcessButton() { diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateRepoActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateRepoActivity.java index c231068d..88d6028a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateRepoActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateRepoActivity.java @@ -2,16 +2,17 @@ package org.mian.gitnex.activities; import android.content.Context; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; -import android.widget.Spinner; import androidx.annotation.NonNull; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; @@ -37,15 +38,18 @@ public class CreateRepoActivity extends BaseActivity { public ImageView closeActivity; private View.OnClickListener onClickListener; - private Spinner spinner; + private AutoCompleteTextView spinner; private Button createRepo; private EditText repoName; private EditText repoDesc; private CheckBox repoAccess; - final Context ctx = this; - private Context appCtx; - List organizationsList = new ArrayList<>(); + private String loginUid; + private String userLogin; + + private String selectedOwner; + + List organizationsList = new ArrayList<>(); //https://github.com/go-gitea/gitea/blob/52cfd2743c0e85b36081cf80a850e6a5901f1865/models/repo.go#L964-L967 final List reservedRepoNames = Arrays.asList(".", ".."); @@ -60,15 +64,11 @@ public class CreateRepoActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(ctx); - TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String userLogin = tinyDb.getString("userLogin"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + loginUid = tinyDB.getString("loginUid"); + userLogin = tinyDB.getString("userLogin"); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); @@ -85,19 +85,7 @@ public class CreateRepoActivity extends BaseActivity { closeActivity.setOnClickListener(onClickListener); spinner = findViewById(R.id.ownerSpinner); - getOrganizations(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), userLogin); - - spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - OrgOwner user = (OrgOwner) parent.getSelectedItem(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }); + getOrganizations(Authorization.get(ctx), userLogin); createRepo = findViewById(R.id.createNewRepoButton); disableProcessButton(); @@ -112,24 +100,15 @@ public class CreateRepoActivity extends BaseActivity { } } - private View.OnClickListener createRepoListener = new View.OnClickListener() { - public void onClick(View v) { - processNewRepo(); - } - }; + private final View.OnClickListener createRepoListener = v -> processNewRepo(); private void processNewRepo() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); AppUtil appUtil = new AppUtil(); - 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 newRepoName = repoName.getText().toString(); String newRepoDesc = repoDesc.getText().toString(); - String repoOwner = spinner.getSelectedItem().toString(); boolean newRepoAccess = repoAccess.isChecked(); if(!connToInternet) { @@ -139,6 +118,7 @@ public class CreateRepoActivity extends BaseActivity { } if(!newRepoDesc.equals("")) { + if (appUtil.charactersLength(newRepoDesc) > 255) { Toasty.warning(ctx, getString(R.string.repoDescError)); @@ -161,32 +141,34 @@ public class CreateRepoActivity extends BaseActivity { else if (reservedRepoPatterns.matcher(newRepoName).find()) { Toasty.warning(ctx, getString(R.string.repoNameErrorReservedPatterns)); + } + else if(selectedOwner == null) { + + Toasty.error(ctx, getString(R.string.repoOwnerError)); } else { disableProcessButton(); - createNewRepository(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess); + createNewRepository(Authorization.get(ctx), loginUid, newRepoName, newRepoDesc, selectedOwner, newRepoAccess); } } - private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) { + private void createNewRepository(final String token, String loginUid, String repoName, String repoDesc, String selectedOwner, boolean isPrivate) { OrganizationRepository createRepository = new OrganizationRepository(true, repoDesc, null, null, repoName, isPrivate, "Default"); Call call; - if(repoOwner.equals(loginUid)) { + if(selectedOwner.equals(loginUid)) { call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .createNewUserRepository(token, createRepository); } else { call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .createNewUserOrgRepository(token, repoOwner, createRepository); + .getApiInterface(ctx) + .createNewUserOrgRepository(token, selectedOwner, createRepository); } call.enqueue(new Callback() { @@ -196,7 +178,7 @@ public class CreateRepoActivity extends BaseActivity { if(response.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); tinyDb.putBoolean("repoCreated", true); Toasty.success(ctx, getString(R.string.repoCreated)); enableProcessButton(); @@ -220,7 +202,6 @@ public class CreateRepoActivity extends BaseActivity { enableProcessButton(); Toasty.error(ctx, getString(R.string.repoCreatedError)); } - } @Override @@ -232,13 +213,10 @@ public class CreateRepoActivity extends BaseActivity { }); } - private void getOrganizations(String instanceUrl, String instanceToken, final String userLogin) { - - TinyDB tinyDb = new TinyDB(appCtx); + private void getOrganizations(String instanceToken, final String userLogin) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getOrgOwners(instanceToken); call.enqueue(new Callback>() { @@ -246,59 +224,58 @@ public class CreateRepoActivity extends BaseActivity { @Override public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response) { - if(response.isSuccessful()) { - if(response.code() == 200) { + if(response.code() == 200) { - int organizationId = 0; + int organizationId = 0; - List organizationsList_ = response.body(); + List organizationsList_ = response.body(); - organizationsList.add(new OrgOwner(userLogin)); - assert organizationsList_ != null; - if(organizationsList_.size() > 0) { + organizationsList.add(new OrgOwner(userLogin)); + assert organizationsList_ != null; - for (int i = 0; i < organizationsList_.size(); i++) { + if(organizationsList_.size() > 0) { - if(!tinyDb.getString("organizationId").isEmpty()) { + for(int i = 0; i < organizationsList_.size(); i++) { - if (Integer.parseInt(tinyDb.getString("organizationId")) == organizationsList_.get(i).getId()) { - organizationId = i + 1; - } - } + if(!tinyDB.getString("organizationId").isEmpty()) { - OrgOwner data = new OrgOwner( - organizationsList_.get(i).getUsername() - ); - organizationsList.add(data); + if(Integer.parseInt(tinyDB.getString("organizationId")) == organizationsList_.get(i).getId()) { + organizationId = i + 1; + } + } - } - } + OrgOwner data = new OrgOwner(organizationsList_.get(i).getUsername()); + organizationsList.add(data); + } + } - ArrayAdapter adapter = new ArrayAdapter<>(CreateRepoActivity.this, - R.layout.spinner_item, organizationsList); + ArrayAdapter adapter = new ArrayAdapter<>(CreateRepoActivity.this, R.layout.list_spinner_items, organizationsList); - adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); - spinner.setAdapter(adapter); + spinner.setAdapter(adapter); - if (tinyDb.getBoolean("organizationAction") & organizationId != 0) { + spinner.setOnItemClickListener ((parent, view, position, id) -> selectedOwner = organizationsList.get(position).getUsername()); - spinner.setSelection(organizationId); - tinyDb.putBoolean("organizationAction", false); - } + if(tinyDB.getBoolean("organizationAction") & organizationId != 0) { - enableProcessButton(); + int selectOwnerById = organizationId; + new Handler(Looper.getMainLooper()).postDelayed(() -> { - } - } - else if(response.code() == 401) { + spinner.setText(organizationsList.get(selectOwnerById).getUsername(), false); + selectedOwner = organizationsList.get(selectOwnerById).getUsername(); + }, 500); - enableProcessButton(); - AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), - getResources().getString(R.string.alertDialogTokenRevokedMessage), - getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), - getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } + tinyDB.putBoolean("organizationAction", false); + } + enableProcessButton(); + } + + else if(response.code() == 401) { + + enableProcessButton(); + AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), + getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + } } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateTeamByOrgActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateTeamByOrgActivity.java index 7f7739de..0abc64be 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateTeamByOrgActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateTeamByOrgActivity.java @@ -31,8 +31,6 @@ import retrofit2.Callback; public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener { - final Context ctx = CreateTeamByOrgActivity.this; - private Context appCtx; private View.OnClickListener onClickListener; private TextView teamName; private TextView teamDesc; @@ -41,7 +39,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic private TextView teamAccessControls; private TextView teamAccessControlsArray; private Button createTeamButton; - private String[] permissionList = {"Read", "Write", "Admin"}; + private final String[] permissionList = {"Read", "Write", "Admin"}; public int permissionSelectedChoice = -1; @Override @@ -49,7 +47,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic return R.layout.activity_create_team_by_org; } - private String[] accessControlsList = new String[] { + private final String[] accessControlsList = new String[] { "Code", "Issues", "Pull Request", @@ -61,7 +59,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic private List pushAccessList; - private boolean[] selectedAccessControlsTrueFalse = new boolean[]{ + private final boolean[] selectedAccessControlsTrueFalse = new boolean[]{ false, false, false, @@ -75,7 +73,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -102,12 +99,8 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx); pBuilder.setTitle(R.string.newTeamPermission); - if(permissionSelectedChoice != -1) { - pBuilder.setCancelable(true); - } - else { - pBuilder.setCancelable(false); - } + pBuilder.setCancelable(permissionSelectedChoice != -1); + pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, (dialogInterface, i) -> { permissionSelectedChoice = i; @@ -136,15 +129,12 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic } dialogInterface.dismiss(); - }); AlertDialog pDialog = pBuilder.create(); pDialog.show(); - }); - teamAccessControls.setOnClickListener(v -> { teamAccessControls.setText(""); @@ -189,6 +179,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic } if(value){ + teamAccessControls.setText(getString(R.string.newTeamPermissionValues, teamAccessControls.getText(), pushAccessList.get(selectedVal))); teamAccessControlsArray.setText(getString(R.string.newTeamPermissionValuesFinal, teamAccessControlsArray.getText(), repoCode)); } @@ -198,15 +189,16 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic String data = String.valueOf(teamAccessControls.getText()); if(!data.equals("")) { + teamAccessControls.setText(data.substring(0, data.length() - 2)); } String dataArray = String.valueOf(teamAccessControlsArray.getText()); + if(!dataArray.equals("")) { + teamAccessControlsArray.setText(dataArray.substring(0, dataArray.length() - 2)); } - //Log.i("orgName", String.valueOf(teamAccessControlsArray.getText())); - }); AlertDialog aDialog = aDialogBuilder.create(); @@ -222,21 +214,18 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic shape.setCornerRadius( 8 ); shape.setColor(getResources().getColor(R.color.hintColor)); createTeamButton.setBackground(shape); - - } else { + } + else { createTeamButton.setEnabled(true); createTeamButton.setOnClickListener(this); - } - } private void processCreateTeam() { AppUtil appUtil = new AppUtil(); - final TinyDB tinyDb = new TinyDB(appCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final String orgName = tinyDb.getString("orgName");; @@ -251,64 +240,60 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if (newTeamName.equals("")) { Toasty.error(ctx, getString(R.string.teamNameEmpty)); return; - } if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { Toasty.warning(ctx, getString(R.string.teamNameError)); return; - } if(!newTeamDesc.equals("")) { if(!appUtil.checkStrings(newTeamDesc)) { + Toasty.warning(ctx, getString(R.string.teamDescError)); return; } if(newTeamDesc.length() > 100) { + Toasty.warning(ctx, getString(R.string.teamDescLimit)); return; } - } if (newTeamPermission.equals("")) { Toasty.error(ctx, getString(R.string.teamPermissionEmpty)); return; - } List newTeamAccessControls_ = new ArrayList<>(Arrays.asList(newTeamAccessControls.split(","))); for (int i = 0; i < newTeamAccessControls_.size(); i++) { + newTeamAccessControls_.set(i, newTeamAccessControls_.get(i).trim()); } - createNewTeamCall(instanceUrl, instanceToken, orgName, newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls_, loginUid); - + createNewTeamCall(instanceToken, orgName, newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls_, loginUid); } - private void createNewTeamCall(final String instanceUrl, final String instanceToken, String orgName, String newTeamName, String newTeamDesc, String newTeamPermission, List newTeamAccessControls, String loginUid) { + private void createNewTeamCall(final String instanceToken, String orgName, String newTeamName, String newTeamDesc, String newTeamPermission, List newTeamAccessControls, String loginUid) { Teams createNewTeamJson = new Teams(newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls); Call call3; call3 = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .createTeamsByOrg(Authorization.returnAuthentication(ctx, loginUid, instanceToken), orgName, createNewTeamJson); + .getApiInterface(ctx) + .createTeamsByOrg(Authorization.get(ctx), orgName, createNewTeamJson); call3.enqueue(new Callback() { @@ -316,15 +301,15 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response2) { if(response2.isSuccessful()) { + if(response2.code() == 201) { - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); tinyDb.putBoolean("resumeTeams", true); Toasty.success(ctx, getString(R.string.teamCreated)); finish(); } - } else if(response2.code() == 404) { @@ -341,7 +326,6 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic Toasty.error(ctx, getString(R.string.teamCreatedError)); } - } @Override @@ -356,6 +340,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic public void onClick(View v) { if(v == createTeamButton) { + processCreateTeam(); } } diff --git a/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java new file mode 100644 index 00000000..cdb39050 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java @@ -0,0 +1,455 @@ +package org.mian.gitnex.activities; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.View; +import androidx.annotation.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.mian.gitnex.R; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.database.api.RepositoriesApi; +import org.mian.gitnex.database.api.UserAccountsApi; +import org.mian.gitnex.database.models.Repository; +import org.mian.gitnex.database.models.UserAccount; +import org.mian.gitnex.databinding.ActivityDeeplinksBinding; +import org.mian.gitnex.helpers.UrlHelper; +import org.mian.gitnex.models.PullRequests; +import org.mian.gitnex.models.UserRepositories; +import java.net.URI; +import java.util.List; +import java.util.Objects; +import io.mikael.urlbuilder.UrlBuilder; +import retrofit2.Call; +import retrofit2.Callback; + +/** + * Author M M Arif + */ + +public class DeepLinksActivity extends BaseActivity { + + private ActivityDeeplinksBinding viewBinding; + private String currentInstance; + private String instanceToken; + private boolean accountFound = false; + + private Intent mainIntent; + private Intent issueIntent; + private Intent repoIntent; + + @Override + protected int getLayoutResourceId() { + + return R.layout.activity_deeplinks; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + + viewBinding = ActivityDeeplinksBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); + + mainIntent = new Intent(ctx, MainActivity.class); + issueIntent = new Intent(ctx, IssueDetailActivity.class); + repoIntent = new Intent(ctx, RepoDetailActivity.class); + + Intent intent = getIntent(); + Uri data = intent.getData(); + assert data != null; + + // check for login + if(!tinyDB.getBoolean("loggedInMode")) { + + finish(); + ctx.startActivity(new Intent(ctx, LoginActivity.class)); + } + + // check for the links(URI) to be in the db + UserAccountsApi userAccountsApi = new UserAccountsApi(ctx); + List userAccounts = userAccountsApi.usersAccounts(); + + for(UserAccount userAccount : userAccounts) { + + String hostUri = userAccount.getInstanceUrl(); + + currentInstance = userAccount.getInstanceUrl(); + instanceToken = userAccount.getToken(); + + if(hostUri.toLowerCase().contains(Objects.requireNonNull(data.getHost().toLowerCase()))) { + + accountFound = true; + break; + } + } + + if(accountFound) { + + // redirect to proper fragment/activity, If no action is there, show options where user to want to go like repos, profile, notifications etc + if(data.getPathSegments().size() > 0) { + + viewBinding.progressBar.setVisibility(View.GONE); + String[] restOfUrl = Objects.requireNonNull(data.getPath()).split("/"); + + if(data.getPathSegments().contains("issues")) { // issue + + if(!Objects.requireNonNull(data.getLastPathSegment()).contains("issues") & StringUtils.isNumeric(data.getLastPathSegment())) { + + issueIntent.putExtra("issueNumber", data.getLastPathSegment()); + + tinyDB.putString("issueNumber", data.getLastPathSegment()); + tinyDB.putString("issueType", "Issue"); + + tinyDB.putString("repoFullName", restOfUrl[restOfUrl.length - 4] + "/" + restOfUrl[restOfUrl.length - 3]); + + final String repoOwner = restOfUrl[restOfUrl.length - 4]; + final String repoName = restOfUrl[restOfUrl.length - 3]; + + int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId"); + RepositoriesApi repositoryData = new RepositoriesApi(ctx); + + Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName); + + if(count == 0) { + + long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", id); + } + else { + + Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", dataRepo.getRepositoryId()); + } + + ctx.startActivity(issueIntent); + finish(); + } + else if(Objects.requireNonNull(data.getLastPathSegment()).contains("issues")) { + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "issue"); + }, 500); + } + else { + + ctx.startActivity(mainIntent); + finish(); + } + } + else if(data.getPathSegments().contains("pulls")) { // pr + + if(!Objects.requireNonNull(data.getLastPathSegment()).contains("pulls") & StringUtils.isNumeric(data.getLastPathSegment())) { + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + getPullRequest(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 4], restOfUrl[restOfUrl.length - 3], Integer.parseInt(data.getLastPathSegment())); + }, 500); + + } + else if(Objects.requireNonNull(data.getLastPathSegment()).contains("pulls")) { + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 3], restOfUrl[restOfUrl.length - 2], "pull"); + }, 500); + } + else { + + ctx.startActivity(mainIntent); + finish(); + } + } + else if(data.getPathSegments().contains("commit")) { // commits (no API yet to properly implement) + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 4], restOfUrl[restOfUrl.length - 3], "pull"); + }, 500); + } + else if(!restOfUrl[restOfUrl.length - 2].equals("") & !restOfUrl[restOfUrl.length - 1].equals("")) { // go to repo + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + goToRepoSection(currentInstance, instanceToken, restOfUrl[restOfUrl.length - 2], restOfUrl[restOfUrl.length - 1], "repo"); + }, 500); + } + else { // no action, show options + + if(tinyDB.getInt("defaultScreenId") == 1) { // repos + + mainIntent.putExtra("launchFragmentByLinkHandler", "repos"); + ctx.startActivity(mainIntent); + finish(); + } + else if(tinyDB.getInt("defaultScreenId") == 2) { // org + + mainIntent.putExtra("launchFragmentByLinkHandler", "org"); + ctx.startActivity(mainIntent); + finish(); + } + else if(tinyDB.getInt("defaultScreenId") == 3) { // notifications + + mainIntent.putExtra("launchFragmentByLinkHandler", "notification"); + ctx.startActivity(mainIntent); + finish(); + } + else if(tinyDB.getInt("defaultScreenId") == 4) { // explore + + mainIntent.putExtra("launchFragmentByLinkHandler", "explore"); + ctx.startActivity(mainIntent); + finish(); + } + else if(tinyDB.getInt("defaultScreenId") == 0) { // show options + + viewBinding.noActionFrame.setVisibility(View.VISIBLE); + viewBinding.addNewAccountFrame.setVisibility(View.GONE); + + viewBinding.repository.setOnClickListener(repository -> { + + tinyDB.putInt("defaultScreenId", 1); + mainIntent.putExtra("launchFragmentByLinkHandler", "repos"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.organization.setOnClickListener(organization -> { + + tinyDB.putInt("defaultScreenId", 2); + mainIntent.putExtra("launchFragmentByLinkHandler", "org"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.notification.setOnClickListener(notification -> { + + tinyDB.putInt("defaultScreenId", 3); + mainIntent.putExtra("launchFragmentByLinkHandler", "notification"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.explore.setOnClickListener(explore -> { + + tinyDB.putInt("defaultScreenId", 4); + mainIntent.putExtra("launchFragmentByLinkHandler", "explore"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.launchApp2.setOnClickListener(launchApp2 -> { + + tinyDB.putInt("defaultScreenId", 0); + ctx.startActivity(mainIntent); + finish(); + }); + } + } + } + else { + + startActivity(mainIntent); + finish(); + } + } + else { + + viewBinding.progressBar.setVisibility(View.GONE); + viewBinding.addNewAccountFrame.setVisibility(View.VISIBLE); + viewBinding.noActionFrame.setVisibility(View.GONE); + viewBinding.addAccountText.setText(String.format(getResources().getString(R.string.accountDoesNotExist), data.getHost())); + + viewBinding.addNewAccount.setOnClickListener(addNewAccount -> { + + Intent accountIntent = new Intent(ctx, AddNewAccountActivity.class); + startActivity(accountIntent); + finish(); + }); + + viewBinding.openInBrowser.setOnClickListener(addNewAccount -> { + + Integer port = data.getPort() >= 0 ? data.getPort() : null; + + URI host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https")) + .withPort(port) + .toUri(); + + Intent intentBrowser = new Intent(); + + intentBrowser.setAction(Intent.ACTION_VIEW); + intentBrowser.addCategory(Intent.CATEGORY_BROWSABLE); + intentBrowser.setData(Uri.parse(String.valueOf(host))); + + startActivity(intentBrowser); + finish(); + + }); + + viewBinding.launchApp.setOnClickListener(launchApp -> { + + startActivity(mainIntent); + finish(); + }); + } + } + + private void getPullRequest(String url, String token, String repoOwner, String repoName, int index) { + + Call call = RetrofitClient + .getApiInterface(ctx, url) + .getPullRequestByIndex(token, repoOwner, repoName, index); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + PullRequests prInfo = response.body(); + + if (response.code() == 200) { + + assert prInfo != null; + + issueIntent.putExtra("issueNumber", index); + issueIntent.putExtra("prMergeable", prInfo.isMergeable()); + + if(prInfo.getHead() != null) { + + issueIntent.putExtra("prHeadBranch", prInfo.getHead().getRef()); + tinyDB.putString("prHeadBranch", prInfo.getHead().getRef()); + + if(prInfo.getHead().getRepo() != null) { + + tinyDB.putString("prIsFork", String.valueOf(prInfo.getHead().getRepo().isFork())); + tinyDB.putString("prForkFullName", prInfo.getHead().getRepo().getFull_name()); + } + else { + + // pull was done from a deleted fork + tinyDB.putString("prIsFork", "true"); + tinyDB.putString("prForkFullName", ctx.getString(R.string.prDeletedFrok)); + } + } + + tinyDB.putString("issueNumber", String.valueOf(index)); + tinyDB.putString("prMergeable", String.valueOf(prInfo.isMergeable())); + tinyDB.putString("issueType", "Pull"); + + tinyDB.putString("repoFullName", repoOwner + "/" + repoName); + + int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId"); + RepositoriesApi repositoryData = new RepositoriesApi(ctx); + + Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName); + + if(count == 0) { + + long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", id); + } + else { + + Repository dataRepo = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", dataRepo.getRepositoryId()); + } + + ctx.startActivity(issueIntent); + finish(); + } + + else { + + ctx.startActivity(issueIntent); + finish(); + Log.e("onFailure-links-pr", String.valueOf(response.code())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + ctx.startActivity(issueIntent); + finish(); + Log.e("onFailure-links-pr", t.toString()); + } + }); + } + + private void goToRepoSection(String url, String token, String repoOwner, String repoName, String type) { + + Call call = RetrofitClient + .getApiInterface(ctx, url) + .getUserRepository(token, repoOwner, repoName); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + UserRepositories repoInfo = response.body(); + + if (response.code() == 200) { + + assert repoInfo != null; + + repoIntent.putExtra("repoFullName", repoInfo.getFullName()); + repoIntent.putExtra("goToSection", "yes"); + repoIntent.putExtra("goToSectionType", type); + + tinyDB.putString("repoFullName", repoInfo.getFullName()); + if(repoInfo.getPrivateFlag()) { + + tinyDB.putString("repoType", getResources().getString(R.string.strPrivate)); + } + else { + + tinyDB.putString("repoType", getResources().getString(R.string.strPublic)); + } + tinyDB.putBoolean("isRepoAdmin", repoInfo.getPermissions().isAdmin()); + tinyDB.putString("repoBranch", repoInfo.getDefault_branch()); + + int currentActiveAccountId = tinyDB.getInt("currentActiveAccountId"); + RepositoriesApi repositoryData = new RepositoriesApi(ctx); + + Integer count = repositoryData.checkRepository(currentActiveAccountId, repoOwner, repoName); + + if(count == 0) { + + long id = repositoryData.insertRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", id); + } + else { + + Repository data = repositoryData.getRepository(currentActiveAccountId, repoOwner, repoName); + tinyDB.putLong("repositoryId", data.getRepositoryId()); + } + + ctx.startActivity(repoIntent); + finish(); + } + + else { + + ctx.startActivity(mainIntent); + finish(); + Log.e("onFailure-goToRepo", String.valueOf(response.code())); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + ctx.startActivity(mainIntent); + finish(); + Log.e("onFailure-goToRepo", t.toString()); + } + }); + } +} diff --git a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java index 9c0b84c6..0e8b6344 100644 --- a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java @@ -4,31 +4,28 @@ import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.content.Context; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; 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.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.StaticGlobalVariables; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; -import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Milestones; @@ -39,7 +36,6 @@ import java.util.Calendar; import java.util.List; import retrofit2.Call; import retrofit2.Callback; -import retrofit2.Response; /** * Author M M Arif @@ -47,45 +43,46 @@ import retrofit2.Response; public class EditIssueActivity extends BaseActivity implements View.OnClickListener { - final Context ctx = this; - private Context appCtx; private View.OnClickListener onClickListener; private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private EditText editIssueTitle; - private SocialAutoCompleteTextView editIssueDescription; + private EditText editIssueDescription; private TextView editIssueDueDate; private Button editIssueButton; - private Spinner editIssueMilestoneSpinner; + private AutoCompleteTextView editIssueMilestoneSpinner; private String msState = "open"; + private int milestoneId; List milestonesList = new ArrayList<>(); - private ArrayAdapter defaultMentionAdapter; + + private String loginUid; + private String instanceToken; + private String repoOwner; + private String repoName; + private int issueIndex; @Override protected int getLayoutResourceId(){ return R.layout.activity_edit_issue; } + @SuppressLint("ClickableViewAccessibility") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - 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"); + 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")); ImageView closeActivity = findViewById(R.id.close); editIssueButton = findViewById(R.id.editIssueButton); @@ -95,7 +92,8 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe editIssueDueDate = findViewById(R.id.editIssueDueDate); // if gitea is 1.12 or higher use the new limit - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } @@ -103,110 +101,49 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe assert imm != null; imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT); - defaultMentionAdapter = new MentionArrayAdapter<>(this); - loadCollaboratorsList(); + editIssueDescription.setOnTouchListener((touchView, motionEvent) -> { + + touchView.getParent().requestDisallowInterceptTouchEvent(true); + + if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + + touchView.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); editIssueMilestoneSpinner = findViewById(R.id.editIssueMilestoneSpinner); - editIssueDescription.setMentionAdapter(defaultMentionAdapter); - initCloseListener(); closeActivity.setOnClickListener(onClickListener); editIssueDueDate.setOnClickListener(this); editIssueButton.setOnClickListener(this); - if(!tinyDb.getString("issueNumber").isEmpty()) { + if(!tinyDB.getString("issueNumber").isEmpty()) { + + if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { - if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) { toolbar_title.setText(getString(R.string.editPrNavHeader, String.valueOf(issueIndex))); } else { + toolbar_title.setText(getString(R.string.editIssueNavHeader, String.valueOf(issueIndex))); } } disableProcessButton(); - getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); - - - } - - public void loadCollaboratorsList() { - - 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()); - } - - }); + getIssue(instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); } private void initCloseListener() { - onClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - finish(); - } - }; + + onClickListener = view -> finish(); } private void processEditIssue() { 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"); - final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - - Milestones mModel = (Milestones) editIssueMilestoneSpinner.getSelectedItem(); - - int editIssueMilestoneId = mModel.getId(); String editIssueTitleForm = editIssueTitle.getText().toString(); String editIssueDescriptionForm = editIssueDescription.getText().toString(); @@ -216,45 +153,34 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if (editIssueTitleForm.equals("")) { Toasty.error(ctx, getString(R.string.issueTitleEmpty)); return; - } - /*if (editIssueDescriptionForm.equals("")) { - - Toasty.info(ctx, getString(R.string.issueDescriptionEmpty)); - return; - - }*/ - if (editIssueDueDateForm.equals("")) { + editIssueDueDateForm = null; - } else { + } + else { + editIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(editIssueDueDateForm))); } - //Log.i("editIssueDueDateForm", String.valueOf(editIssueDueDateForm)); disableProcessButton(); - editIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, editIssueMilestoneId); - + editIssue(instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm, milestoneId); } - private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int editIssueMilestoneId) { + private void editIssue(String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate, int milestoneId) { - final TinyDB tinyDb = new TinyDB(appCtx); - - CreateIssue issueData = new CreateIssue(title, description, dueDate, editIssueMilestoneId); + CreateIssue issueData = new CreateIssue(title, description, dueDate, milestoneId); Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .patchIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData); + .getApiInterface(ctx) + .patchIssue(Authorization.get(ctx), repoOwner, repoName, issueIndex, issueData); call.enqueue(new Callback() { @@ -263,17 +189,18 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe if(response.code() == 201) { - if(tinyDb.getString("issueType").equalsIgnoreCase("Pull")) { + if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { + Toasty.success(ctx, getString(R.string.editPrSuccessMessage)); } else { + Toasty.success(ctx, getString(R.string.editIssueSuccessMessage)); } - tinyDb.putBoolean("issueEdited", true); - tinyDb.putBoolean("resumeIssues", true); + tinyDB.putBoolean("issueEdited", true); + tinyDB.putBoolean("resumeIssues", true); finish(); - } else if(response.code() == 401) { @@ -282,19 +209,17 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else { enableProcessButton(); Toasty.error(ctx, getString(R.string.genericError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); enableProcessButton(); } @@ -302,7 +227,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe } - @Override public void onClick(View v) { @@ -314,31 +238,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe 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) { - - editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)); - - } - }, mYear, mMonth, mDay); + (view, year, monthOfYear, dayOfMonth) -> editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth)), mYear, mMonth, mDay); datePickerDialog.show(); - } else if(v == editIssueButton) { + processEditIssue(); } } - private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) { + private void getIssue(final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) { Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + .getApiInterface(ctx) + .getIssueByIndex(Authorization.get(ctx), repoOwner, repoName, issueIndex); call.enqueue(new Callback() { @@ -351,27 +265,27 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe editIssueTitle.setText(response.body().getTitle()); editIssueDescription.setText(response.body().getBody()); - int msId = 0; + int currentMilestoneId = 0; if(response.body().getMilestone() != null) { - msId = response.body().getMilestone().getId(); + + currentMilestoneId = response.body().getMilestone().getId(); } // get milestones list if(response.body().getId() > 0) { Call> call_ = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); + .getApiInterface(ctx) + .getMilestones(Authorization.get(ctx), repoOwner, repoName, 1, resultLimit, msState); - final int finalMsId = msId; + int checkMilestoneId = currentMilestoneId; - call_.enqueue(new Callback>() { + call_.enqueue(new Callback>() { @Override public void onResponse(@NonNull Call> call, @NonNull retrofit2.Response> response_) { - int finalMsId1 = 0; + int getSelectedMilestoneId = 0; if (response_.code() == 200) { @@ -379,39 +293,40 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe milestonesList.add(new Milestones(0, "No milestone")); assert milestonesList_ != null; + if (milestonesList_.size() > 0) { + + milestonesList.addAll(milestonesList_); + for (int i = 0; i < milestonesList_.size(); i++) { - Milestones data = new Milestones( - milestonesList_.get(i).getId(), - milestonesList_.get(i).getTitle() - ); - milestonesList.add(data); - - if(finalMsId == milestonesList_.get(i).getId()) { - finalMsId1 = i + 1; + if(checkMilestoneId == milestonesList_.get(i).getId()) { + getSelectedMilestoneId = i + 1; } - } } - ArrayAdapter adapter_ = new ArrayAdapter<>(EditIssueActivity.this, - R.layout.spinner_item, milestonesList); + ArrayAdapter adapter = new ArrayAdapter<>(EditIssueActivity.this, + R.layout.list_spinner_items, milestonesList); - adapter_.setDropDownViewResource(R.layout.spinner_dropdown_item); - editIssueMilestoneSpinner.setAdapter(adapter_); + editIssueMilestoneSpinner.setAdapter(adapter); + + editIssueMilestoneSpinner.setOnItemClickListener ((parent, view, position, id) -> milestoneId = milestonesList.get(position).getId()); + + int finalMsId = getSelectedMilestoneId; + new Handler(Looper.getMainLooper()).postDelayed(() -> { + + editIssueMilestoneSpinner.setText(milestonesList.get(finalMsId).getTitle(),false); + milestoneId = milestonesList.get(finalMsId).getId(); + }, 500); - if(milestonesList_.size() > 0) { - editIssueMilestoneSpinner.setSelection(finalMsId1); - } enableProcessButton(); - } - } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); } }); @@ -439,11 +354,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe 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/FileDiffActivity.java b/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java index 62827d23..8200119e 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java @@ -1,6 +1,5 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.View; @@ -14,7 +13,6 @@ import org.mian.gitnex.R; import org.mian.gitnex.adapters.FilesDiffAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.ParseDiff; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; @@ -36,8 +34,6 @@ public class FileDiffActivity extends BaseActivity { private TextView toolbarTitle; private ListView mListView; private ProgressBar mProgressBar; - final Context ctx = this; - private Context appCtx; @Override protected int getLayoutResourceId() { @@ -49,12 +45,11 @@ public class FileDiffActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - final TinyDB tinyDb = new TinyDB(appCtx); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; @@ -77,28 +72,21 @@ public class FileDiffActivity extends BaseActivity { String pullIndex = tinyDb.getString("issueNumber"); - boolean apiCall = true; - String instanceUrl = tinyDb.getString("instanceUrl"); - - // fallback for old gitea instances - if(new Version(tinyDb.getString("giteaVersion")).less("1.13.0")) { - - apiCall = false; - instanceUrl = instanceUrl.substring(0, instanceUrl.lastIndexOf("api/v1/")); - } - - getPullDiffContent(instanceUrl, repoOwner, repoName, pullIndex, instanceToken, apiCall); + boolean apiCall = !new Version(tinyDb.getString("giteaVersion")).less("1.13.0"); + getPullDiffContent(repoOwner, repoName, pullIndex, instanceToken, apiCall); } - private void getPullDiffContent(String instanceUrl, String owner, String repo, String pullIndex, String token, boolean apiCall) { + private void getPullDiffContent(String owner, String repo, String pullIndex, String token, boolean apiCall) { Call call; if(apiCall) { - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getPullDiffContent(token, owner, repo, pullIndex); + + call = RetrofitClient.getApiInterface(ctx).getPullDiffContent(token, owner, repo, pullIndex); } else { - call = RetrofitClient.getInstance(instanceUrl, ctx).getWebInterface().getPullDiffContent(owner, repo, pullIndex); + + call = RetrofitClient.getWebInterface(ctx).getPullDiffContent(owner, repo, pullIndex); } call.enqueue(new Callback() { @@ -109,16 +97,18 @@ public class FileDiffActivity extends BaseActivity { if(response.code() == 200) { try { + assert response.body() != null; - AppUtil appUtil = new AppUtil(); List fileContentsArray = ParseDiff.getFileDiffViewArray(response.body().string()); int filesCount = fileContentsArray.size(); if(filesCount > 1) { + toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount))); } else { + toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount))); } @@ -126,34 +116,28 @@ public class FileDiffActivity extends BaseActivity { mListView.setAdapter(adapter); mProgressBar.setVisibility(View.GONE); - } catch(IOException e) { + e.printStackTrace(); } - } 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.labelGeneralError)); - } - } @Override @@ -174,5 +158,4 @@ public class FileDiffActivity extends BaseActivity { }; } - } diff --git a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java index 4586a4ac..f3cc9040 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java @@ -1,6 +1,6 @@ package org.mian.gitnex.activities; -import android.content.Context; +import android.app.Activity; import android.content.Intent; import android.graphics.BitmapFactory; import android.graphics.Typeface; @@ -8,7 +8,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; -import android.text.Spanned; import android.text.method.ScrollingMovementMethod; import android.util.Base64; import android.util.Log; @@ -21,8 +20,11 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import com.github.barteksc.pdfviewer.PDFView; import com.github.barteksc.pdfviewer.util.FitPolicy; @@ -33,7 +35,7 @@ import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.fragments.BottomSheetFileViewerFragment; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; -import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.highlightjs.HighlightJsView; import org.mian.gitnex.helpers.highlightjs.models.Theme; @@ -43,24 +45,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.util.Collection; -import java.util.Collections; import java.util.Objects; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.core.CorePlugin; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.ext.tables.TablePlugin; -import io.noties.markwon.ext.tasklist.TaskListPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.image.DefaultMediaDecoder; -import io.noties.markwon.image.ImageItem; -import io.noties.markwon.image.ImagesPlugin; -import io.noties.markwon.image.SchemeHandler; -import io.noties.markwon.image.gif.GifMediaDecoder; -import io.noties.markwon.image.svg.SvgMediaDecoder; -import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Call; import retrofit2.Callback; @@ -75,8 +60,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie private LinearLayout singleFileContentsFrame; private HighlightJsView singleCodeContents; private PhotoView imageView; - final Context ctx = this; - private Context appCtx; private ProgressBar mProgressBar; private byte[] imageData; private PDFView pdfView; @@ -86,7 +69,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie private String singleFileName; private String fileSha; private AppUtil appUtil; - private TinyDB tinyDb; @Override protected int getLayoutResourceId() { @@ -98,23 +80,20 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); appUtil = new AppUtil(); - tinyDb = new TinyDB(appCtx); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - String repoFullName = tinyDb.getString("repoFullName"); - String repoBranch = tinyDb.getString("repoBranch"); + String repoFullName = tinyDB.getString("repoFullName"); + String repoBranch = tinyDB.getString("repoBranch"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + final String loginUid = tinyDB.getString("loginUid"); + final String instanceToken = "token " + tinyDB.getString(loginUid + "-token"); - tinyDb.putBoolean("enableMarkdownInFileView", false); + tinyDB.putBoolean("enableMarkdownInFileView", false); ImageView closeActivity = findViewById(R.id.close); singleFileContents = findViewById(R.id.singleFileContents); @@ -133,25 +112,22 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie initCloseListener(); closeActivity.setOnClickListener(onClickListener); - tinyDb.putString("downloadFileContents", ""); + tinyDB.putString("downloadFileContents", ""); try { singleFileName = URLDecoder.decode(singleFileName, "UTF-8"); singleFileName = singleFileName.replaceAll("//", "/"); singleFileName = singleFileName.startsWith("/") ? singleFileName.substring(1) : singleFileName; - } catch(UnsupportedEncodingException e) { Log.i("singleFileName", singleFileName); - } toolbar_title.setText(singleFileName); - getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName, repoBranch); - + getSingleFileContents(instanceToken, repoOwner, repoName, singleFileName, repoBranch); } @Override @@ -159,25 +135,25 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie super.onResume(); - String repoFullName = tinyDb.getString("repoFullName"); - String repoBranch = tinyDb.getString("repoBranch"); + String repoFullName = tinyDB.getString("repoFullName"); + String repoBranch = tinyDB.getString("repoBranch"); String[] parts = repoFullName.split("/"); String repoOwner = parts[0]; String repoName = parts[1]; - String instanceUrl = tinyDb.getString("instanceUrl"); - String loginUid = tinyDb.getString("loginUid"); - String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + String loginUid = tinyDB.getString("loginUid"); + String instanceToken = "token " + tinyDB.getString(loginUid + "-token"); - if(tinyDb.getBoolean("fileModified")) { - getSingleFileContents(instanceUrl, instanceToken, repoOwner, repoName, singleFileName, repoBranch); - tinyDb.putBoolean("fileModified", false); + if(tinyDB.getBoolean("fileModified")) { + + getSingleFileContents(instanceToken, repoOwner, repoName, singleFileName, repoBranch); + tinyDB.putBoolean("fileModified", false); } } - private void getSingleFileContents(String instanceUrl, String token, final String owner, String repo, final String filename, String ref) { + private void getSingleFileContents(String token, final String owner, String repo, final String filename, String ref) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getSingleFileContents(token, owner, repo, filename, ref); + Call call = RetrofitClient.getApiInterface(ctx).getSingleFileContents(token, owner, repo, filename, ref); call.enqueue(new Callback() { @@ -196,8 +172,8 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie fileSha = response.body().getSha(); // download file meta - tinyDb.putString("downloadFileName", filename); - tinyDb.putString("downloadFileContents", response.body().getContent()); + tinyDB.putString("downloadFileName", filename); + tinyDB.putString("downloadFileContents", response.body().getContent()); if(appUtil.imageExtension(fileExtension)) { // file is image @@ -209,7 +185,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT); Drawable imageDrawable = new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(imageData, 0, imageData.length)); imageView.setImageDrawable(imageDrawable); - } else if(appUtil.sourceCodeExtension(fileExtension)) { // file is sourcecode @@ -218,28 +193,34 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie pdfViewFrame.setVisibility(View.GONE); singleCodeContents.setVisibility(View.VISIBLE); - switch(tinyDb.getInt("fileviewerSourceCodeThemeId")) { + switch(tinyDB.getInt("fileviewerSourceCodeThemeId")) { + case 1: + singleCodeContents.setTheme(Theme.ARDUINO_LIGHT); break; case 2: + singleCodeContents.setTheme(Theme.GITHUB); break; case 3: + singleCodeContents.setTheme(Theme.FAR); break; case 4: + singleCodeContents.setTheme(Theme.IR_BLACK); break; case 5: + singleCodeContents.setTheme(Theme.ANDROID_STUDIO); break; default: + singleCodeContents.setTheme(Theme.MONOKAI_SUBLIME); } singleCodeContents.setSource(appUtil.decodeBase64(response.body().getContent())); - } else if(appUtil.pdfExtension(fileExtension)) { // file is pdf @@ -248,7 +229,7 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie singleCodeContents.setVisibility(View.GONE); pdfViewFrame.setVisibility(View.VISIBLE); - pdfNightMode = tinyDb.getBoolean("enablePdfMode"); + pdfNightMode = tinyDB.getBoolean("enablePdfMode"); decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT); pdfView.fromBytes(decodedPdf).enableSwipe(true).swipeHorizontal(false).enableDoubletap(true).defaultPage(0).enableAnnotationRendering(false).password(null).scrollHandle(null).enableAntialiasing(true).spacing(0).autoSpacing(true).pageFitPolicy(FitPolicy.WIDTH).fitEachPage(true).pageSnap(false).pageFling(true).nightMode(pdfNightMode).load(); @@ -264,7 +245,6 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie singleFileContents.setText(getResources().getString(R.string.excludeFilesInFileviewer)); singleFileContents.setGravity(Gravity.CENTER); singleFileContents.setTypeface(null, Typeface.BOLD); - } else { // file type not known - plain text view @@ -274,37 +254,30 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie singleFileContentsFrame.setVisibility(View.VISIBLE); singleFileContents.setText(appUtil.decodeBase64(response.body().getContent())); - } - } else { + singleFileContents.setText(""); mProgressBar.setVisibility(View.GONE); } - } 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.labelGeneralError)); - } - } @Override @@ -324,7 +297,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie inflater.inflate(R.menu.files_view_menu, menu); String fileExtension = FileUtils.getExtension(singleFileName); + if(!fileExtension.equalsIgnoreCase("md")) { + menu.getItem(0).setVisible(false); } @@ -336,89 +311,42 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie int id = item.getItemId(); - switch(id) { - case android.R.id.home: + if(id == android.R.id.home) { - finish(); - return true; - case R.id.genericMenu: - - BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment(); - bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet"); - return true; - case R.id.markdown: - - final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create()) - .usePlugin(ImagesPlugin.create(plugin -> { - plugin.addSchemeHandler(new SchemeHandler() { - - @NonNull - @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = ctx.getResources().getIdentifier( - raw.substring("drawable://".length()), - "drawable", - ctx.getPackageName()); - - final Drawable drawable = ctx.getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); - } - - @NonNull - @Override - public Collection supportedSchemes() { - - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(ctx.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(ctx.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - - builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(getResources().getColor(R.color.lightBlue)); - } - }) - .usePlugin(TablePlugin.create(ctx)) - .usePlugin(TaskListPlugin.create(ctx)) - .usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create()) - .build(); - - if(!tinyDb.getBoolean("enableMarkdownInFileView")) { - - singleCodeContents.setVisibility(View.GONE); - singleFileContentsFrame.setVisibility(View.VISIBLE); - singleFileContents.setVisibility(View.VISIBLE); - Spanned bodyWithMD = markwon.toMarkdown(appUtil.decodeBase64(tinyDb.getString("downloadFileContents"))); - markwon.setParsedMarkdown(singleFileContents, bodyWithMD); - tinyDb.putBoolean("enableMarkdownInFileView", true); - } - else { - - singleCodeContents.setVisibility(View.VISIBLE); - singleFileContentsFrame.setVisibility(View.GONE); - singleFileContents.setVisibility(View.GONE); - singleCodeContents.setSource(appUtil.decodeBase64(tinyDb.getString("downloadFileContents"))); - tinyDb.putBoolean("enableMarkdownInFileView", false); - } - - return true; - default: - return super.onOptionsItemSelected(item); + finish(); + return true; } + else if(id == R.id.genericMenu) { + BottomSheetFileViewerFragment bottomSheet = new BottomSheetFileViewerFragment(); + bottomSheet.show(getSupportFragmentManager(), "fileViewerBottomSheet"); + return true; + } + else if(id == R.id.markdown) { + + new Markdown(ctx, appUtil.decodeBase64(tinyDB.getString("downloadFileContents")), singleFileContents); + + if(!tinyDB.getBoolean("enableMarkdownInFileView")) { + + singleCodeContents.setVisibility(View.GONE); + singleFileContentsFrame.setVisibility(View.VISIBLE); + singleFileContents.setVisibility(View.VISIBLE); + tinyDB.putBoolean("enableMarkdownInFileView", true); + } + else { + + singleCodeContents.setVisibility(View.VISIBLE); + singleFileContentsFrame.setVisibility(View.GONE); + singleFileContents.setVisibility(View.GONE); + singleCodeContents.setSource(appUtil.decodeBase64(tinyDB.getString("downloadFileContents"))); + tinyDB.putBoolean("enableMarkdownInFileView", false); + } + return true; + } + else { + + return super.onOptionsItemSelected(item); + } } @Override @@ -432,15 +360,18 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie if("deleteFile".equals(text)) { String fileExtension = FileUtils.getExtension(singleFileName); - String data = appUtil.decodeBase64(tinyDb.getString("downloadFileContents")); + String data = appUtil.decodeBase64(tinyDB.getString("downloadFileContents")); Intent intent = new Intent(ctx, CreateFileActivity.class); intent.putExtra("fileAction", 1); intent.putExtra("filePath", singleFileName); intent.putExtra("fileSha", fileSha); + if(!appUtil.imageExtension(fileExtension)) { + intent.putExtra("fileContents", data); } else { + intent.putExtra("fileContents", ""); } @@ -450,15 +381,18 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie if("editFile".equals(text)) { String fileExtension = FileUtils.getExtension(singleFileName); - String data = appUtil.decodeBase64(tinyDb.getString("downloadFileContents")); + String data = appUtil.decodeBase64(tinyDB.getString("downloadFileContents")); Intent intent = new Intent(ctx, CreateFileActivity.class); intent.putExtra("fileAction", 2); intent.putExtra("filePath", singleFileName); intent.putExtra("fileSha", fileSha); + if(!appUtil.imageExtension(fileExtension)) { + intent.putExtra("fileContents", data); } else { + intent.putExtra("fileContents", ""); } @@ -469,11 +403,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie private void requestFileDownload() { - if(!tinyDb.getString("downloadFileContents").isEmpty()) { + if(!tinyDB.getString("downloadFileContents").isEmpty()) { - int CREATE_REQUEST_CODE = 40; - - File outputFileName = new File(tinyDb.getString("downloadFileName")); + File outputFileName = new File(tinyDB.getString("downloadFileName")); Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); @@ -481,48 +413,48 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie intent.setType("*/*"); intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName()); - startActivityForResult(intent, CREATE_REQUEST_CODE); - + fileDownloadActivityResultLauncher.launch(intent); } else { Toasty.warning(ctx, getString(R.string.waitLoadingDownloadFile)); } - } - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + ActivityResultLauncher fileDownloadActivityResultLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { - super.onActivityResult(requestCode, resultCode, data); + @Override + public void onActivityResult(ActivityResult result) { - if(requestCode == 40 && resultCode == RESULT_OK) { + if (result.getResultCode() == Activity.RESULT_OK) { - try { + Intent data = result.getData(); - assert data != null; - Uri uri = data.getData(); + try { - assert uri != null; - OutputStream outputStream = getContentResolver().openOutputStream(uri); + assert data != null; + Uri uri = data.getData(); - byte[] dataAsBytes = Base64.decode(tinyDb.getString("downloadFileContents"), 0); + assert uri != null; + OutputStream outputStream = getContentResolver().openOutputStream(uri); - assert outputStream != null; - outputStream.write(dataAsBytes); - outputStream.close(); + byte[] dataAsBytes = Base64.decode(tinyDB.getString("downloadFileContents"), 0); - Toasty.success(ctx, getString(R.string.downloadFileSaved)); + assert outputStream != null; + outputStream.write(dataAsBytes); + outputStream.close(); + Toasty.success(ctx, getString(R.string.downloadFileSaved)); + + } + catch(IOException e) { + + Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); + } } - catch(IOException e) { - - Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); - } - } - - } + }); private void initCloseListener() { 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 716cfa4d..1d7a7026 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -1,18 +1,15 @@ 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; @@ -50,11 +47,11 @@ import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.LabelWidthCalculator; +import org.mian.gitnex.helpers.Markdown; 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; @@ -62,30 +59,15 @@ 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 org.mian.gitnex.views.ReactionList; 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; -import io.noties.markwon.Markwon; -import io.noties.markwon.core.CorePlugin; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.ext.tables.TablePlugin; -import io.noties.markwon.ext.tasklist.TaskListPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.image.DefaultMediaDecoder; -import io.noties.markwon.image.ImageItem; -import io.noties.markwon.image.ImagesPlugin; -import io.noties.markwon.image.SchemeHandler; -import io.noties.markwon.image.gif.GifMediaDecoder; -import io.noties.markwon.image.svg.SvgMediaDecoder; -import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -97,13 +79,7 @@ import retrofit2.Response; public class IssueDetailActivity extends BaseActivity implements LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener, BottomSheetSingleIssueFragment.BottomSheetListener { private IssueCommentsAdapter adapter; - final Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; - private String instanceUrl; - private String loginUid; - private String instanceToken; private String repoOwner; private String repoName; private int issueIndex; @@ -135,21 +111,16 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); viewBinding = ActivityIssueDetailBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); setContentView(view); - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - String repoFullName = tinyDb.getString("repoFullName"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); repoOwner = parts[0]; repoName = parts[1]; - issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); + issueIndex = Integer.parseInt(tinyDB.getString("issueNumber")); setSupportActionBar(viewBinding.toolbar); Objects.requireNonNull(getSupportActionBar()).setTitle(repoName); @@ -162,12 +133,18 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL); viewBinding.recyclerView.addItemDecoration(dividerItemDecoration); - viewBinding.addNewComment.setOnClickListener(v -> BottomSheetReplyFragment.newInstance(new Bundle()).show(getSupportFragmentManager(), "replyBottomSheet")); + viewBinding.addNewComment.setOnClickListener(v -> { + + BottomSheetReplyFragment bottomSheetReplyFragment = BottomSheetReplyFragment.newInstance(new Bundle()); + bottomSheetReplyFragment.setOnInteractedListener(this::onResume); + bottomSheetReplyFragment.show(getSupportFragmentManager(), "replyBottomSheet"); + + }); 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); + LabelsActions.getCurrentIssueLabels(ctx, repoOwner, repoName, issueIndex, currentLabelsIds); + AssigneesActions.getCurrentIssueAssignees(ctx, repoOwner, repoName, issueIndex, currentAssignees); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -196,14 +173,14 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.pullToRefresh.setRefreshing(false); IssueCommentsViewModel - .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, + .loadIssueComments(Authorization.get(ctx), repoOwner, repoName, issueIndex, ctx); }, 500)); Typeface myTypeface; - switch(tinyDb.getInt("customFontId", -1)) { + switch(tinyDB.getInt("customFontId", -1)) { case 1: myTypeface = Typeface.createFromAsset(Objects.requireNonNull(ctx).getAssets(), "fonts/manroperegular.ttf"); @@ -222,8 +199,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.toolbarTitle.setTypeface(myTypeface); viewBinding.toolbarTitle.setText(repoName); - getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); - fetchDataAsync(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); + getSingleIssue(repoOwner, repoName, issueIndex); + fetchDataAsync(repoOwner, repoName, issueIndex); } @@ -232,6 +209,10 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt switch(text) { + case "onResume": + onResume(); + break; + case "showLabels": showLabels(); break; @@ -292,7 +273,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt } }); - AssigneesActions.getRepositoryAssignees(ctx, instanceUrl, instanceToken, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); + dialogAssignees.show(); + AssigneesActions.getRepositoryAssignees(ctx, repoOwner, repoName, assigneesList, dialogAssignees, assigneesAdapter, assigneesBinding); } public void showLabels() { @@ -328,7 +310,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt } }); - LabelsActions.getRepositoryLabels(ctx, instanceUrl, instanceToken, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); + dialogLabels.show(); + LabelsActions.getRepositoryLabels(ctx, repoOwner, repoName, labelsList, dialogLabels, labelsAdapter, labelsBinding); } private void updateIssueAssignees() { @@ -338,9 +321,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt Call call3; call3 = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .patchIssueAssignees(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson); + .getApiInterface(ctx) + .patchIssueAssignees(Authorization.get(ctx), repoOwner, repoName, issueIndex, updateAssigneeJson); call3.enqueue(new Callback() { @@ -355,9 +337,9 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.frameAssignees.removeAllViews(); viewBinding.frameLabels.removeAllViews(); - getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); + getSingleIssue(repoOwner, repoName, issueIndex); currentAssignees.clear(); - new Handler(Looper.getMainLooper()).postDelayed(() -> AssigneesActions.getCurrentIssueAssignees(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentAssignees), 1000); + new Handler(Looper.getMainLooper()).postDelayed(() -> AssigneesActions.getCurrentIssueAssignees(ctx, repoOwner, repoName, issueIndex, currentAssignees), 1000); } else if(response2.code() == 401) { @@ -394,9 +376,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt Labels patchIssueLabels = new Labels(labelsIds); Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .updateIssueLabels(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels); + .getApiInterface(ctx) + .updateIssueLabels(Authorization.get(ctx), repoOwner, repoName, issueIndex, patchIssueLabels); call.enqueue(new Callback() { @@ -410,9 +391,9 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.frameAssignees.removeAllViews(); viewBinding.frameLabels.removeAllViews(); - getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); + getSingleIssue(repoOwner, repoName, issueIndex); currentLabelsIds.clear(); - new Handler(Looper.getMainLooper()).postDelayed(() -> LabelsActions.getCurrentIssueLabels(ctx, instanceUrl, loginUid, instanceToken, repoOwner, repoName, issueIndex, currentLabelsIds), 1000); + new Handler(Looper.getMainLooper()).postDelayed(() -> LabelsActions.getCurrentIssueLabels(ctx, repoOwner, repoName, issueIndex, currentLabelsIds), 1000); } else if(response.code() == 401) { @@ -457,18 +438,21 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt int id = item.getItemId(); - switch(id) { - case android.R.id.home: - finish(); - return true; - case R.id.genericMenu: - BottomSheetSingleIssueFragment bottomSheet = new BottomSheetSingleIssueFragment(); - bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } + if(id == android.R.id.home) { + finish(); + return true; + } + else if(id == R.id.genericMenu) { + + BottomSheetSingleIssueFragment bottomSheet = new BottomSheetSingleIssueFragment(); + bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet"); + return true; + } + else { + + return super.onOptionsItemSelected(item); + } } @Override @@ -476,84 +460,87 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt super.onResume(); - if(tinyDb.getBoolean("commentPosted")) { + if(tinyDB.getBoolean("commentPosted")) { + viewBinding.scrollViewComments.post(() -> { IssueCommentsViewModel - .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, + .loadIssueComments(Authorization.get(ctx), repoOwner, repoName, issueIndex, ctx); new Handler(Looper.getMainLooper()).postDelayed(() -> viewBinding.scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN), 1000); - tinyDb.putBoolean("commentPosted", false); - + tinyDB.putBoolean("commentPosted", false); }); } - if(tinyDb.getBoolean("commentEdited")) { + if(tinyDB.getBoolean("commentEdited")) { + viewBinding.scrollViewComments.post(() -> { IssueCommentsViewModel - .loadIssueComments(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, + .loadIssueComments(Authorization.get(ctx), repoOwner, repoName, issueIndex, ctx); - tinyDb.putBoolean("commentEdited", false); - + tinyDB.putBoolean("commentEdited", false); }); } - if(tinyDb.getBoolean("singleIssueUpdate")) { + if(tinyDB.getBoolean("singleIssueUpdate")) { new Handler(Looper.getMainLooper()).postDelayed(() -> { viewBinding.frameAssignees.removeAllViews(); viewBinding.frameLabels.removeAllViews(); - getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); - tinyDb.putBoolean("singleIssueUpdate", false); + getSingleIssue(repoOwner, repoName, issueIndex); + tinyDB.putBoolean("singleIssueUpdate", false); }, 500); - } - if(tinyDb.getBoolean("issueEdited")) { + if(tinyDB.getBoolean("issueEdited")) { new Handler(Looper.getMainLooper()).postDelayed(() -> { viewBinding.frameAssignees.removeAllViews(); viewBinding.frameLabels.removeAllViews(); - getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid); - tinyDb.putBoolean("issueEdited", false); + getSingleIssue(repoOwner, repoName, issueIndex); + tinyDB.putBoolean("issueEdited", false); }, 500); - } - } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo, int index, String loginUid) { + private void fetchDataAsync(String owner, String repo, int index) { IssueCommentsViewModel issueCommentsModel = new ViewModelProvider(this).get(IssueCommentsViewModel.class); - issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), owner, repo, index, ctx) + issueCommentsModel.getIssueCommentList(Authorization.get(ctx), owner, repo, index, ctx) .observe(this, issueCommentsMain -> { assert issueCommentsMain != null; if(issueCommentsMain.size() > 0) { + viewBinding.divider.setVisibility(View.VISIBLE); } - adapter = new IssueCommentsAdapter(ctx, getSupportFragmentManager(), issueCommentsMain); + Bundle bundle = new Bundle(); + bundle.putString("repoOwner", repoOwner); + bundle.putString("repoName", repoName); + bundle.putInt("issueNumber", issueIndex); + + adapter = new IssueCommentsAdapter(ctx, bundle, issueCommentsMain, getSupportFragmentManager(), this::onResume); + viewBinding.recyclerView.setAdapter(adapter); }); - } - private void getSingleIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid) { + private void getSingleIssue(String repoOwner, String repoName, int issueIndex) { - final TinyDB tinyDb = new TinyDB(appCtx); - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface() - .getIssueByIndex(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); + Call call = RetrofitClient.getApiInterface(ctx) + .getIssueByIndex(Authorization.get(ctx), repoOwner, repoName, issueIndex); call.enqueue(new Callback() { @@ -566,6 +553,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt assert singleIssue != null; viewBinding.issuePrState.setVisibility(View.VISIBLE); + if(singleIssue.getPull_request() != null) { if(singleIssue.getPull_request().isMerged()) { // merged @@ -586,49 +574,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.issuePrState.setImageResource(R.drawable.ic_issue_closed_red); } - final Markwon markwon = Markwon.builder(Objects.requireNonNull(ctx)).usePlugin(CorePlugin.create()) - .usePlugin(ImagesPlugin.create(plugin -> { - plugin.addSchemeHandler(new SchemeHandler() { - - @NonNull - @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = ctx.getResources() - .getIdentifier(raw.substring("drawable://".length()), "drawable", ctx.getPackageName()); - - final Drawable drawable = ctx.getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); - } - - @NonNull - @Override - public Collection supportedSchemes() { - - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(ctx.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(ctx.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - - })).usePlugin(new AbstractMarkwonPlugin() { - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - - builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(getResources().getColor(R.color.lightBlue)); - } - }).usePlugin(TablePlugin.create(ctx)).usePlugin(TaskListPlugin.create(ctx)).usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build(); - - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); final String locale = tinyDb.getString("locale"); final String timeFormat = tinyDb.getString("dateFormat"); tinyDb.putString("issueState", singleIssue.getState()); @@ -641,8 +587,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt .getString(R.string.hash) + singleIssue.getNumber() + ""; viewBinding.issueTitle.setText(Html.fromHtml(issueNumber_ + " " + singleIssue.getTitle())); String cleanIssueDescription = singleIssue.getBody().trim(); - Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription)); - markwon.setParsedMarkdown(viewBinding.issueDescription, UserMentions.UserMentionsFunc(ctx, bodyWithMD, cleanIssueDescription)); + + new Markdown(ctx, EmojiParser.parseToUnicode(cleanIssueDescription), viewBinding.issueDescription); RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) viewBinding.issueDescription.getLayoutParams(); @@ -650,7 +596,9 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt params1.setMargins(15, 0, 0, 0); if(singleIssue.getAssignees() != null) { + viewBinding.assigneesScrollView.setVisibility(View.VISIBLE); + for(int i = 0; i < singleIssue.getAssignees().size(); i++) { ImageView assigneesView = new ImageView(ctx); @@ -662,17 +610,19 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.frameAssignees.addView(assigneesView); assigneesView.setLayoutParams(params1); if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) { + assigneesView.setOnClickListener( new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), ctx)); } else { + assigneesView.setOnClickListener( new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), ctx)); } - } } else { + viewBinding.assigneesScrollView.setVisibility(View.GONE); } @@ -681,6 +631,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt params.setMargins(0, 0, 15, 0); if(singleIssue.getLabels() != null) { + viewBinding.labelsScrollView.setVisibility(View.VISIBLE); for(int i = 0; i < singleIssue.getLabels().size(); i++) { @@ -704,16 +655,17 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt labelsView.setImageDrawable(drawable); viewBinding.frameLabels.addView(labelsView); - } } else { + viewBinding.labelsScrollView.setVisibility(View.GONE); } if(singleIssue.getDue_date() != null) { if(timeFormat.equals("normal") || timeFormat.equals("pretty")) { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); String dueDate = formatter.format(singleIssue.getDue_date()); viewBinding.issueDueDate.setText(dueDate); @@ -721,11 +673,11 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt .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()); viewBinding.issueDueDate.setText(dueDate); } - } else { @@ -735,6 +687,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt String edited; if(!singleIssue.getUpdated_at().equals(singleIssue.getCreated_at())) { + edited = getString(R.string.colorfulBulletSpan) + getString(R.string.modifiedText); viewBinding.issueModified.setVisibility(View.VISIBLE); viewBinding.issueModified.setText(edited); @@ -742,22 +695,27 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getUpdated_at()), ctx)); } else { + viewBinding.issueModified.setVisibility(View.INVISIBLE); } if((singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) && singleIssue.getAssignees() != null) { + paramsDesc.setMargins(0, 35, 0, 0); viewBinding.issueDescription.setLayoutParams(paramsDesc); } else if(singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) { + paramsDesc.setMargins(0, 55, 0, 0); viewBinding.issueDescription.setLayoutParams(paramsDesc); } else if(singleIssue.getAssignees() == null) { + paramsDesc.setMargins(0, 35, 0, 0); viewBinding.issueDescription.setLayoutParams(paramsDesc); } else { + paramsDesc.setMargins(0, 15, 0, 0); viewBinding.issueDescription.setLayoutParams(paramsDesc); } @@ -766,30 +724,51 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.issueCreatedTime.setVisibility(View.VISIBLE); if(timeFormat.equals("pretty")) { + viewBinding.issueCreatedTime .setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), ctx)); } + Bundle bundle = new Bundle(); + bundle.putString("repoOwner", repoOwner); + bundle.putString("repoName", repoName); + bundle.putInt("issueId", singleIssue.getNumber()); + + ReactionList reactionList = new ReactionList(ctx, bundle); + + viewBinding.commentReactionBadges.removeAllViews(); + viewBinding.commentReactionBadges.addView(reactionList); + + reactionList.setOnReactionAddedListener(() -> { + + if(viewBinding.commentReactionBadges.getVisibility() != View.VISIBLE) { + viewBinding.commentReactionBadges.post(() -> viewBinding.commentReactionBadges.setVisibility(View.VISIBLE)); + } + }); + if(singleIssue.getMilestone() != null) { + + viewBinding.issueMilestone.setVisibility(View.VISIBLE); viewBinding.issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle())); } else { + viewBinding.issueMilestone.setVisibility(View.GONE); } if(!singleIssue.getUser().getFull_name().equals("")) { + viewBinding.assigneeAvatar.setOnClickListener( new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx)); } else { + viewBinding.assigneeAvatar.setOnClickListener( new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx)); } viewBinding.progressBar.setVisibility(View.GONE); - } - else if(response.code() == 401) { AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), @@ -798,7 +777,21 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); } + else if(response.code() == 404) { + if(tinyDb.getString("issueType").equals("Issue")) { + + Toasty.warning(ctx, getResources().getString(R.string.noDataIssueTab)); + } + else if(tinyDb.getString("issueType").equals("Pull")) { + + Toasty.warning(ctx, getResources().getString(R.string.noDataPullRequests)); + } + + Intent mainIntent = new Intent(ctx, MainActivity.class); + ctx.startActivity(mainIntent); + finish(); + } } @Override @@ -811,8 +804,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - Call call2 = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface() - .checkIssueWatchStatus(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex); + Call call2 = RetrofitClient.getApiInterface(appCtx) + .checkIssueWatchStatus(Authorization.get(ctx), repoOwner, repoName, issueIndex); call2.enqueue(new Callback() { @@ -823,21 +816,17 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt assert response.body() != null; tinyDb.putBoolean("issueSubscribed", response.body().getSubscribed()); - } else { tinyDb.putBoolean("issueSubscribed", false); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { tinyDb.putBoolean("issueSubscribed", false); - } }); 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 e7016da7..049b5978 100644 --- a/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/LoginActivity.java @@ -1,16 +1,15 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.util.Log; import android.view.View; -import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; import android.widget.RadioGroup; -import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; @@ -19,7 +18,7 @@ import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.database.api.UserAccountsApi; import org.mian.gitnex.database.models.UserAccount; import org.mian.gitnex.helpers.AppUtil; -import org.mian.gitnex.helpers.NetworkObserver; +import org.mian.gitnex.helpers.NetworkStatusObserver; import org.mian.gitnex.helpers.PathsHelper; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; @@ -47,16 +46,12 @@ public class LoginActivity extends BaseActivity { private enum LoginType {BASIC, TOKEN} - private Context appCtx; - private Context ctx = this; - private TinyDB tinyDB; - private Button loginButton; private EditText instanceUrlET, loginUidET, loginPassword, otpCode, loginTokenCode; - private Spinner protocolSpinner; - private TextView otpInfo; + private AutoCompleteTextView protocolSpinner; private RadioGroup loginMethod; private String device_id = "token"; + private String selectedProtocol; @Override protected int getLayoutResourceId() { @@ -68,70 +63,77 @@ public class LoginActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDB = new TinyDB(appCtx); - NetworkObserver networkMonitor = new NetworkObserver(ctx); + NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.get(ctx); loginButton = findViewById(R.id.login_button); instanceUrlET = findViewById(R.id.instance_url); loginUidET = findViewById(R.id.login_uid); loginPassword = findViewById(R.id.login_passwd); otpCode = findViewById(R.id.otpCode); - otpInfo = findViewById(R.id.otpInfo); protocolSpinner = findViewById(R.id.httpsSpinner); loginMethod = findViewById(R.id.loginMethod); loginTokenCode = findViewById(R.id.loginTokenCode); ((TextView) findViewById(R.id.appVersion)).setText(AppUtil.getAppVersion(appCtx)); - ArrayAdapter adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.spinner_item, Protocol.values()); - adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item); + ArrayAdapter adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values()); protocolSpinner.setAdapter(adapterProtocols); - protocolSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + protocolSpinner.setSelection(0); + protocolSpinner.setOnItemClickListener((parent, view, position, id) -> { - public void onItemSelected(AdapterView parent, View view, int pos, long id) { + selectedProtocol = String.valueOf(parent.getItemAtPosition(position)); - if(protocolSpinner.getSelectedItem() == Protocol.HTTP) { - Toasty.warning(ctx, getResources().getString(R.string.protocolError)); - } + if(selectedProtocol.equals(String.valueOf(Protocol.HTTP))) { + + Toasty.warning(ctx, getResources().getString(R.string.protocolError)); } - - public void onNothingSelected(AdapterView parent) { - - } - }); + if(R.id.loginToken == loginMethod.getCheckedRadioButtonId()) { + + AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); + findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE); + } + else { + + AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); + findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE); + } + loginMethod.setOnCheckedChangeListener((group, checkedId) -> { if(checkedId == R.id.loginToken) { - AppUtil.setMultiVisibility(View.GONE, loginUidET, loginPassword, otpCode, otpInfo); - loginTokenCode.setVisibility(View.VISIBLE); - + AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); + findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE); } else { - AppUtil.setMultiVisibility(View.VISIBLE, loginUidET, loginPassword, otpCode, otpInfo); - loginTokenCode.setVisibility(View.GONE); - + AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout)); + findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE); } }); - networkMonitor.onInternetStateListener(isAvailable -> { + Handler handler = new Handler(getMainLooper()); - if(isAvailable) { + networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> { - enableProcessButton(); - } - else { + handler.post(() -> { - disableProcessButton(); - loginButton.setText(getResources().getString(R.string.btnLogin)); - Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); - } + if(hasNetworkConnection) { + + enableProcessButton(); + } + else { + + disableProcessButton(); + loginButton.setText(getResources().getString(R.string.btnLogin)); + Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); + } + + }); }); loadDefaults(); @@ -140,25 +142,29 @@ public class LoginActivity extends BaseActivity { disableProcessButton(); login(); - }); - } private void login() { try { + if(selectedProtocol == null) { + + Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError)); + enableProcessButton(); + return; + } + String loginUid = loginUidET.getText().toString(); String loginPass = loginPassword.getText().toString(); String loginToken = loginTokenCode.getText().toString().trim(); - Protocol protocol = (Protocol) protocolSpinner.getSelectedItem(); LoginType loginType = (loginMethod.getCheckedRadioButtonId() == R.id.loginUsernamePassword) ? LoginType.BASIC : LoginType.TOKEN; URI rawInstanceUrl = UrlBuilder.fromString(UrlHelper.fixScheme(instanceUrlET.getText().toString(), "http")).toUri(); - URI instanceUrl = UrlBuilder.fromUri(rawInstanceUrl).withScheme(protocol.name().toLowerCase()).withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/")) + URI instanceUrl = UrlBuilder.fromUri(rawInstanceUrl).withScheme(selectedProtocol.toLowerCase()).withPath(PathsHelper.join(rawInstanceUrl.getPath(), "/api/v1/")) .toUri(); tinyDB.putString("loginType", loginType.name().toLowerCase()); @@ -170,7 +176,6 @@ public class LoginActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL)); enableProcessButton(); return; - } if(loginType == LoginType.BASIC) { @@ -180,14 +185,12 @@ public class LoginActivity extends BaseActivity { Toasty.warning(ctx, getResources().getString(R.string.loginOTPTypeError)); enableProcessButton(); return; - } if(rawInstanceUrl.getUserInfo() != null) { tinyDB.putString("basicAuthPassword", loginPass); tinyDB.putBoolean("basicAuthFlag", true); - } if(loginUid.equals("")) { @@ -195,7 +198,6 @@ public class LoginActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.emptyFieldUsername)); enableProcessButton(); return; - } if(loginPass.equals("")) { @@ -203,13 +205,12 @@ public class LoginActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.emptyFieldPassword)); enableProcessButton(); return; - } int loginOTP = (otpCode.length() > 0) ? Integer.parseInt(otpCode.getText().toString().trim()) : 0; tinyDB.putString("loginUid", loginUid); - versionCheck(instanceUrl.toString(), loginUid, loginPass, loginOTP, loginToken, loginType); + versionCheck(loginUid, loginPass, loginOTP, loginToken, loginType); } else { @@ -219,11 +220,9 @@ public class LoginActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.loginTokenError)); enableProcessButton(); return; - } - versionCheck(instanceUrl.toString(), loginUid, loginPass, 123, loginToken, loginType); - + versionCheck(loginUid, loginPass, 123, loginToken, loginType); } } @@ -232,27 +231,25 @@ public class LoginActivity extends BaseActivity { Log.e("onFailure-login", e.toString()); Toasty.error(ctx, getResources().getString(R.string.malformedUrl)); enableProcessButton(); - } } - private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken, + private void versionCheck(final String loginUid, final String loginPass, final int loginOTP, final String loginToken, final LoginType loginType) { Call callVersion; if(!loginToken.equals("")) { - callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken("token " + loginToken); + callVersion = RetrofitClient.getApiInterface(appCtx).getGiteaVersionWithToken("token " + loginToken); } else { String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8); callVersion = - (loginOTP != 0) ? RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithOTP(credential, loginOTP) : - RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithBasic(credential); - + (loginOTP != 0) ? RetrofitClient.getApiInterface(appCtx).getGiteaVersionWithOTP(credential, loginOTP) : + RetrofitClient.getApiInterface(appCtx).getGiteaVersionWithBasic(credential); } callVersion.enqueue(new Callback() { @@ -263,9 +260,10 @@ public class LoginActivity extends BaseActivity { if(responseVersion.code() == 200) { GiteaVersion version = responseVersion.body(); - assert version != null; + if(!Version.valid(version.getVersion())) { + Toasty.error(ctx, getResources().getString(R.string.versionUnknown)); enableProcessButton(); return; @@ -276,8 +274,10 @@ public class LoginActivity extends BaseActivity { if(gitea_version.less(getString(R.string.versionLow))) { - AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader)) - .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning) + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx) + .setTitle(getString(R.string.versionAlertDialogHeader)) + .setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())) + .setIcon(R.drawable.ic_warning) .setCancelable(true); alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> { @@ -289,7 +289,7 @@ public class LoginActivity extends BaseActivity { alertDialogBuilder.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> { dialog.dismiss(); - login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken); + login(loginType, loginUid, loginPass, loginOTP, loginToken); }); alertDialogBuilder.create().show(); @@ -297,32 +297,34 @@ public class LoginActivity extends BaseActivity { } else if(gitea_version.lessOrEqual(getString(R.string.versionHigh))) { - login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken); + login(loginType, loginUid, loginPass, loginOTP, loginToken); } else { Toasty.warning(ctx, getResources().getString(R.string.versionUnsupportedNew)); - login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken); + login(loginType, loginUid, loginPass, loginOTP, loginToken); } } else if(responseVersion.code() == 403) { - login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken); + login(loginType, loginUid, loginPass, loginOTP, loginToken); } } - private void login(LoginType loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken) { + private void login(LoginType loginType, String loginUid, String loginPass, int loginOTP, String loginToken) { // ToDo: before store/create token: get UserInfo to check DB/AccountManager if there already exist a token // the setup methods then can better handle all different cases if(loginType == LoginType.BASIC) { - setup(instanceUrl, loginUid, loginPass, loginOTP); + + setup(loginUid, loginPass, loginOTP); } else if(loginType == LoginType.TOKEN) { // Token - setupUsingExistingToken(instanceUrl, loginToken); + + setupUsingExistingToken(loginToken); } } @@ -336,9 +338,9 @@ public class LoginActivity extends BaseActivity { }); } - private void setupUsingExistingToken(String instanceUrl, final String loginToken) { + private void setupUsingExistingToken(final String loginToken) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken); + Call call = RetrofitClient.getApiInterface(appCtx).getUserInfo("token " + loginToken); call.enqueue(new Callback() { @@ -350,6 +352,7 @@ public class LoginActivity extends BaseActivity { switch(response.code()) { case 200: + assert userDetails != null; tinyDB.putBoolean("loggedInMode", true); tinyDB.putString(userDetails.getLogin() + "-token", loginToken); @@ -357,14 +360,14 @@ public class LoginActivity extends BaseActivity { tinyDB.putString("userLogin", userDetails.getUsername()); // insert new account to db if does not exist - String accountName = userDetails.getUsername() + "@" + instanceUrl; + String accountName = userDetails.getUsername() + "@" + TinyDB.getInstance(ctx).getString("instanceUrl"); UserAccountsApi userAccountsApi = new UserAccountsApi(ctx); int checkAccount = userAccountsApi.getCount(accountName); long accountId; if(checkAccount == 0) { - accountId = userAccountsApi.insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), loginToken, ""); + accountId = userAccountsApi.insertNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), loginToken, ""); tinyDB.putInt("currentActiveAccountId", (int) accountId); } else { @@ -378,18 +381,16 @@ public class LoginActivity extends BaseActivity { startActivity(new Intent(LoginActivity.this, MainActivity.class)); finish(); break; - case 401: + Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError)); enableProcessButton(); break; - default: + Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); enableProcessButton(); - } - } @Override @@ -398,13 +399,12 @@ public class LoginActivity extends BaseActivity { Log.e("onFailure", t.toString()); Toasty.error(ctx, getResources().getString(R.string.genericError)); enableProcessButton(); - } }); } - private void setup(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP) { + private void setup(final String loginUid, final String loginPass, final int loginOTP) { final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8); final String tokenName = "gitnex-app-" + device_id; @@ -412,11 +412,11 @@ public class LoginActivity extends BaseActivity { Call> call; if(loginOTP != 0) { - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokensWithOTP(credential, loginOTP, loginUid); + call = RetrofitClient.getApiInterface(appCtx).getUserTokensWithOTP(credential, loginOTP, loginUid); } else { - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokens(credential, loginUid); + call = RetrofitClient.getApiInterface(appCtx).getUserTokens(credential, loginUid); } call.enqueue(new Callback>() { @@ -429,7 +429,9 @@ public class LoginActivity extends BaseActivity { if(response.code() == 200) { assert userTokens != null; + for(UserTokens t : userTokens) { + if(t.getName().equals(tokenName)) { // this app had created an token on this instance before @@ -438,13 +440,14 @@ public class LoginActivity extends BaseActivity { Call delcall; if(loginOTP != 0) { - delcall = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface() + delcall = RetrofitClient.getApiInterface(ctx) .deleteTokenWithOTP(credential, loginOTP, loginUid, t.getId()); } else { - delcall = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().deleteToken(credential, loginUid, t.getId()); + delcall = RetrofitClient.getApiInterface(ctx).deleteToken(credential, loginUid, t.getId()); } + delcall.enqueue(new Callback() { @Override @@ -452,13 +455,12 @@ public class LoginActivity extends BaseActivity { if(response.code() == 204) { - setupToken(instanceUrl, loginUid, loginPass, loginOTP, tokenName); + setupToken(loginUid, loginPass, loginOTP, tokenName); } else { Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); enableProcessButton(); - } } @@ -468,20 +470,18 @@ public class LoginActivity extends BaseActivity { Log.e("onFailure-login", t.toString()); Toasty.error(ctx, getResources().getString(R.string.malformedJson)); enableProcessButton(); - } }); return; } } - setupToken(instanceUrl, loginUid, loginPass, loginOTP, tokenName); + setupToken(loginUid, loginPass, loginOTP, tokenName); } else { Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); enableProcessButton(); - } } @@ -491,13 +491,12 @@ public class LoginActivity extends BaseActivity { Log.e("onFailure-login", t.toString()); Toasty.error(ctx, getResources().getString(R.string.malformedJson)); enableProcessButton(); - } }); } - private void setupToken(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String tokenName) { + private void setupToken(final String loginUid, final String loginPass, final int loginOTP, final String tokenName) { final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8); @@ -506,12 +505,13 @@ public class LoginActivity extends BaseActivity { if(loginOTP != 0) { - callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface() + callCreateToken = RetrofitClient.getApiInterface(ctx) .createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken); } else { - callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().createNewToken(credential, loginUid, createUserToken); + callCreateToken = RetrofitClient.getApiInterface(ctx) + .createNewToken(credential, loginUid, createUserToken); } callCreateToken.enqueue(new Callback() { @@ -526,7 +526,7 @@ public class LoginActivity extends BaseActivity { if(!newToken.getSha1().equals("")) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface() + Call call = RetrofitClient.getApiInterface(ctx) .getUserInfo("token " + newToken.getSha1()); call.enqueue(new Callback() { @@ -539,6 +539,7 @@ public class LoginActivity extends BaseActivity { switch(response.code()) { case 200: + assert userDetails != null; tinyDB.remove("loginPass"); tinyDB.putBoolean("loggedInMode", true); @@ -547,7 +548,7 @@ public class LoginActivity extends BaseActivity { tinyDB.putString(loginUid + "-token-last-eight", newToken.getToken_last_eight()); // insert new account to db if does not exist - String accountName = userDetails.getUsername() + "@" + instanceUrl; + String accountName = userDetails.getUsername() + "@" + TinyDB.getInstance(ctx).getString("instanceUrl"); UserAccountsApi userAccountsApi = new UserAccountsApi(ctx); int checkAccount = userAccountsApi.getCount(accountName); long accountId; @@ -555,7 +556,7 @@ public class LoginActivity extends BaseActivity { if(checkAccount == 0) { accountId = userAccountsApi - .insertNewAccount(accountName, instanceUrl, userDetails.getUsername(), newToken.getSha1(), ""); + .insertNewAccount(accountName, TinyDB.getInstance(ctx).getString("instanceUrl"), userDetails.getUsername(), newToken.getSha1(), ""); tinyDB.putInt("currentActiveAccountId", (int) accountId); } else { @@ -568,18 +569,16 @@ public class LoginActivity extends BaseActivity { startActivity(new Intent(LoginActivity.this, MainActivity.class)); finish(); break; - case 401: + Toasty.error(ctx, getResources().getString(R.string.unauthorizedApiError)); enableProcessButton(); break; - default: + Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + response.code()); enableProcessButton(); - } - } @Override @@ -588,7 +587,6 @@ public class LoginActivity extends BaseActivity { Log.e("onFailure", t.toString()); Toasty.error(ctx, getResources().getString(R.string.genericError)); enableProcessButton(); - } }); } @@ -597,7 +595,6 @@ public class LoginActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.genericApiStatusError) + responseCreate.code()); enableProcessButton(); - } } @@ -613,17 +610,21 @@ public class LoginActivity extends BaseActivity { private void loadDefaults() { if(tinyDB.getString("loginType").equals(LoginType.BASIC.name().toLowerCase())) { + loginMethod.check(R.id.loginUsernamePassword); } else { + loginMethod.check(R.id.loginToken); } if(!tinyDB.getString("instanceUrlRaw").equals("")) { + instanceUrlET.setText(tinyDB.getString("instanceUrlRaw")); } if(!tinyDB.getString("loginUid").equals("")) { + loginUidET.setText(tinyDB.getString("loginUid")); } @@ -634,9 +635,11 @@ public class LoginActivity extends BaseActivity { } if(!tinyDB.getString("uniqueAppId").isEmpty()) { + device_id = tinyDB.getString("uniqueAppId"); } else { + device_id = UUID.randomUUID().toString(); tinyDB.putString("uniqueAppId", device_id); } diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java index 61922179..f77a8294 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -77,11 +77,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig private ImageView userAvatarBackground; private ViewGroup navHeaderFrame; private TextView toolbarTitle; - final Context ctx = this; - private Context appCtx; private Typeface myTypeface; - private String instanceUrl; private String loginUid; private String instanceToken; @@ -99,63 +96,69 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - final TinyDB tinyDb = new TinyDB(appCtx); - tinyDb.putBoolean("noConnection", false); + tinyDB.putBoolean("noConnection", false); + + String currentVersion = tinyDB.getString("giteaVersion"); Intent mainIntent = getIntent(); String launchFragment = mainIntent.getStringExtra("launchFragment"); - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + loginUid = tinyDB.getString("loginUid"); + instanceToken = "token " + tinyDB.getString(loginUid + "-token"); - if(tinyDb.getString("dateFormat").isEmpty()) { - tinyDb.putString("dateFormat", "pretty"); + if(tinyDB.getString("dateFormat").isEmpty()) { + + tinyDB.putString("dateFormat", "pretty"); } - if(tinyDb.getString("codeBlockStr").isEmpty()) { - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); + if(tinyDB.getString("codeBlockStr").isEmpty()) { + + tinyDB.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); + tinyDB.putInt("codeBlockBackground", getResources().getColor(R.color.black)); } - if(tinyDb.getString("enableCounterIssueBadgeInit").isEmpty()) { - tinyDb.putBoolean("enableCounterIssueBadge", true); + if(tinyDB.getString("enableCounterIssueBadgeInit").isEmpty()) { + + tinyDB.putBoolean("enableCounterIssueBadge", true); } - if(tinyDb.getString("homeScreenStr").isEmpty()) { - tinyDb.putInt("homeScreenId", 0); + if(tinyDB.getString("homeScreenStr").isEmpty()) { + + tinyDB.putString("homeScreenStr", "yes"); + tinyDB.putInt("homeScreenId", 0); } boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - if(!tinyDb.getBoolean("loggedInMode")) { + if(!tinyDB.getBoolean("loggedInMode")) { + logout(this, ctx); return; } - if(tinyDb.getInt("currentActiveAccountId") <= 0) { + if(tinyDB.getInt("currentActiveAccountId") <= 0) { + AlertDialogs.forceLogoutDialog(ctx, getResources().getString(R.string.forceLogoutDialogHeader), getResources().getString(R.string.forceLogoutDialogDescription), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); } Toolbar toolbar = findViewById(R.id.toolbar); toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - switch(tinyDb.getInt("customFontId", -1)) { + switch(tinyDB.getInt("customFontId", -1)) { case 0: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf"); break; - case 2: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf"); break; - default: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf"); break; - } toolbarTitle.setTypeface(myTypeface); @@ -165,37 +168,47 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig Fragment fragmentById = fm.findFragmentById(R.id.fragment_container); if(fragmentById instanceof SettingsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); } else if(fragmentById instanceof MyRepositoriesFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); } else if(fragmentById instanceof StarredRepositoriesFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); } else if(fragmentById instanceof OrganizationsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); } else if(fragmentById instanceof ExploreFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); } else if(fragmentById instanceof NotificationsFragment) { + toolbarTitle.setText(R.string.pageTitleNotifications); } else if(fragmentById instanceof ProfileFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); } else if(fragmentById instanceof DraftsFragment) { + toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); } else if(fragmentById instanceof AdministrationFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); } else if(fragmentById instanceof UserAccountsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleUserAccounts)); } - getNotificationsCount(instanceUrl, instanceToken); + getNotificationsCount(instanceToken); drawer = findViewById(R.id.drawer_layout); NavigationView navigationView = findViewById(R.id.nav_view); @@ -213,20 +226,15 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig @Override public void onDrawerOpened(@NonNull View drawerView) { - getNotificationsCount(instanceUrl, instanceToken); - } + if(tinyDB.getBoolean("noConnection")) { - @Override - public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { - - if(tinyDb.getBoolean("noConnection")) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); - tinyDb.putBoolean("noConnection", false); + tinyDB.putBoolean("noConnection", false); } - String userEmailNav = tinyDb.getString("userEmail"); - String userFullNameNav = tinyDb.getString("userFullname"); - String userAvatarNav = tinyDb.getString("userAvatar"); + String userEmailNav = tinyDB.getString("userEmail"); + String userFullNameNav = tinyDB.getString("userFullname"); + String userAvatarNav = tinyDB.getString("userAvatar"); blurView = hView.findViewById(R.id.blurView); userEmail = hView.findViewById(R.id.userEmail); @@ -252,17 +260,18 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig userAccountsList.addAll(userAccounts); navRecyclerViewUserAccounts.setAdapter(adapterUserAccounts); } - }); userEmail.setTypeface(myTypeface); userFullName.setTypeface(myTypeface); if(!userEmailNav.equals("")) { + userEmail.setText(userEmailNav); } if(!userFullNameNav.equals("")) { + userFullName.setText(userFullNameNav); } @@ -291,14 +300,11 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig .setBlurAlgorithm(new RenderScriptBlur(ctx)) .setBlurRadius(5) .setHasFixedTransformationMatrix(false); - } @Override public void onError(Exception e) {} - }); - } userAvatar.setOnClickListener(v -> { @@ -309,9 +315,13 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig drawer.closeDrawers(); }); - String currentVersion = tinyDb.getString("giteaVersion"); + getNotificationsCount(instanceToken); + } - navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDb.getBoolean("userIsAdmin")); + @Override + public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { + + navigationView.getMenu().findItem(R.id.nav_administration).setVisible(tinyDB.getBoolean("userIsAdmin")); navigationView.getMenu().findItem(R.id.nav_notifications).setVisible(new Version(currentVersion).higherOrEqual("1.12.3")); } @@ -333,98 +343,128 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig switch(launchFragment) { case "drafts": + toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_comments_draft); return; - case "notifications": + toolbarTitle.setText(getResources().getString(R.string.pageTitleNotifications)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_notifications); return; + } + } + String launchFragmentByHandler = mainIntent.getStringExtra("launchFragmentByLinkHandler"); + + if(launchFragmentByHandler != null) { + + mainIntent.removeExtra("launchFragmentByLinkHandler"); + + switch(launchFragmentByHandler) { + + case "repos": + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_repositories); + return; + case "org": + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_organizations); + return; + case "notification": + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_notifications); + return; + case "explore": + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_explore); + return; } } if(savedInstanceState == null) { - if(!new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.3")) { + if(!new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) { - if(tinyDb.getInt("homeScreenId") == 7) { + if(tinyDB.getInt("homeScreenId") == 7) { - tinyDb.putInt("homeScreenId", 0); + tinyDB.putInt("homeScreenId", 0); } } - switch(tinyDb.getInt("homeScreenId")) { + switch(tinyDB.getInt("homeScreenId")) { case 1: + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); navigationView.setCheckedItem(R.id.nav_starred_repos); break; - case 2: + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_organizations); break; - case 3: + toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); navigationView.setCheckedItem(R.id.nav_repositories); break; - case 4: + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); navigationView.setCheckedItem(R.id.nav_profile); break; - case 5: + toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); navigationView.setCheckedItem(R.id.nav_explore); break; - case 6: + toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_comments_draft); break; - case 7: + toolbarTitle.setText(getResources().getString(R.string.pageTitleNotifications)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_notifications); break; - default: + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); navigationView.setCheckedItem(R.id.nav_home); break; - } } if(!connToInternet) { - if(!tinyDb.getBoolean("noConnection")) { + if(!tinyDB.getBoolean("noConnection")) { + Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); } - tinyDb.putBoolean("noConnection", true); - + tinyDB.putBoolean("noConnection", true); } else { - loadUserInfo(instanceUrl, instanceToken, loginUid); - giteaVersion(instanceUrl); - tinyDb.putBoolean("noConnection", false); - + loadUserInfo(instanceToken, loginUid); + giteaVersion(); + tinyDB.putBoolean("noConnection", false); } // Changelog popup @@ -440,10 +480,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig Log.e("changelogDialog", Objects.requireNonNull(e.getMessage())); } - if(versionCode > tinyDb.getInt("versionCode")) { + if(versionCode > tinyDB.getInt("versionCode")) { - tinyDb.putInt("versionCode", versionCode); - tinyDb.putBoolean("versionFlag", true); + tinyDB.putInt("versionCode", versionCode); + tinyDB.putBoolean("versionFlag", true); ChangeLog changelogDialog = new ChangeLog(this); changelogDialog.showDialog(); @@ -458,7 +498,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig @Override public void onButtonClicked(String text) { - TinyDB tinyDb = new TinyDB(ctx); + TinyDB tinyDb = TinyDB.getInstance(ctx); int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId"); if("deleteDrafts".equals(text)) { @@ -482,14 +522,15 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig }) .setNeutralButton(R.string.cancelButton, null).show(); - } else { + Toasty.error(ctx, getResources().getString(R.string.genericError)); } } else { + Toasty.error(ctx, getResources().getString(R.string.genericError)); } @@ -501,74 +542,74 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig public void onBackPressed() { if(drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); } else { + super.onBackPressed(); } - } @Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { - switch(menuItem.getItemId()) { + int id = menuItem.getItemId(); - case R.id.nav_home: - toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); - break; + if(id == R.id.nav_home) { - case R.id.nav_organizations: - toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); + } + else if(id == R.id.nav_organizations) { - case R.id.nav_profile: - toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); + } + else if(id == R.id.nav_profile) { - case R.id.nav_repositories: - toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); + } + else if(id == R.id.nav_repositories) { - case R.id.nav_settings: - toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); + } + else if(id == R.id.nav_settings) { - case R.id.nav_logout: - logout(this, ctx); - overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit(); + } + else if(id == R.id.nav_logout) { - case R.id.nav_starred_repos: - toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); - break; + logout(this, ctx); + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + } + else if(id == R.id.nav_starred_repos) { - case R.id.nav_explore: - toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); + } + else if(id == R.id.nav_explore) { - case R.id.nav_notifications: - toolbarTitle.setText(R.string.pageTitleNotifications); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); + } + else if(id == R.id.nav_notifications) { - case R.id.nav_comments_draft: - toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit(); - break; + toolbarTitle.setText(R.string.pageTitleNotifications); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); + } + else if(id == R.id.nav_comments_draft) { - case R.id.nav_administration: - toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit(); - break; + toolbarTitle.setText(getResources().getString(R.string.titleDrafts)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new DraftsFragment()).commit(); + } + else if(id == R.id.nav_administration) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit(); } drawer.closeDrawer(GravityCompat.START); @@ -577,14 +618,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig public static void logout(Activity activity, Context ctx) { - TinyDB tinyDb = new TinyDB(ctx.getApplicationContext()); - tinyDb.putBoolean("loggedInMode", false); - tinyDb.remove("basicAuthPassword"); - tinyDb.putBoolean("basicAuthFlag", false); + TinyDB tinyDB = TinyDB.getInstance(ctx); + + tinyDB.putBoolean("loggedInMode", false); + tinyDB.remove("basicAuthPassword"); + tinyDB.putBoolean("basicAuthFlag", false); //tinyDb.clear(); activity.finish(); ctx.startActivity(new Intent(ctx, LoginActivity.class)); - } @Override @@ -593,22 +634,22 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig int id = item.getItemId(); if(id == R.id.genericMenu) { + BottomSheetDraftsFragment bottomSheet = new BottomSheetDraftsFragment(); bottomSheet.show(getSupportFragmentManager(), "draftsBottomSheet"); return true; } return super.onOptionsItemSelected(item); - } - private void giteaVersion(final String instanceUrl) { + private void giteaVersion() { - final TinyDB tinyDb = new TinyDB(appCtx); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); - Call callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(token); + Call callVersion = RetrofitClient.getApiInterface(ctx).getGiteaVersionWithToken(token); callVersion.enqueue(new Callback() { @@ -621,7 +662,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig assert version != null; tinyDb.putString("giteaVersion", version.getVersion()); - } } @@ -630,16 +670,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig Log.e("onFailure-version", t.toString()); } - }); - } - private void loadUserInfo(String instanceUrl, String token, String loginUid) { + private void loadUserInfo(String token, String loginUid) { - final TinyDB tinyDb = new TinyDB(appCtx); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(Authorization.returnAuthentication(ctx, loginUid, token)); + Call call = RetrofitClient.getApiInterface(ctx).getUserInfo(Authorization.get(ctx)); call.enqueue(new Callback() { @@ -655,6 +693,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig assert userDetails != null; if(userDetails.getIs_admin() != null) { + tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin()); } @@ -662,9 +701,11 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig tinyDb.putInt("userId", userDetails.getId()); if(!userDetails.getFullname().equals("")) { + tinyDb.putString("userFullname", userDetails.getFullname()); } else { + tinyDb.putString("userFullname", userDetails.getLogin()); } @@ -672,9 +713,11 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig tinyDb.putString("userAvatar", userDetails.getAvatar()); if(userDetails.getLang() != null) { + tinyDb.putString("userLang", userDetails.getLang()); } else { + tinyDb.putString("userLang", ""); } } @@ -682,15 +725,12 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig 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 { String toastError = getResources().getString(R.string.genericApiStatusError) + response.code(); Toasty.error(ctx, toastError); - } - } @Override @@ -702,9 +742,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig } - private void getNotificationsCount(String instanceUrl, String token) { + private void getNotificationsCount(String token) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkUnreadNotifications(token); + Call call = RetrofitClient.getApiInterface(ctx).checkUnreadNotifications(token); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java index 5b6d2f6f..5b217e61 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java @@ -6,30 +6,24 @@ import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; import android.widget.ArrayAdapter; import androidx.annotation.NonNull; import com.google.gson.JsonElement; -import com.hendraanggrian.appcompat.socialview.Mention; -import com.hendraanggrian.appcompat.widget.MentionArrayAdapter; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.ActivityMergePullRequestBinding; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; -import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.MergePullRequest; import org.mian.gitnex.models.MergePullRequestSpinner; import java.util.ArrayList; -import java.util.List; +import java.util.Objects; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; -import retrofit2.Response; /** * Author M M Arif @@ -38,11 +32,13 @@ import retrofit2.Response; public class MergePullRequestActivity extends BaseActivity { private View.OnClickListener onClickListener; - final Context ctx = this; - private Context appCtx; + + private String repoOwner; + private String repoName; + private int prIndex; + private ActivityMergePullRequestBinding viewBinding; - private ArrayAdapter defaultMentionAdapter; private String Do; @Override @@ -56,14 +52,18 @@ public class MergePullRequestActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); viewBinding = ActivityMergePullRequestBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); setContentView(view); + String repoFullName = tinyDB.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + repoOwner = parts[0]; + repoName = parts[1]; + prIndex = Integer.parseInt(tinyDB.getString("issueNumber")); + boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - TinyDB tinyDb = new TinyDB(appCtx); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); @@ -73,53 +73,37 @@ public class MergePullRequestActivity extends BaseActivity { setMergeAdapter(); - viewBinding.mergeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + if(!tinyDB.getString("issueTitle").isEmpty()) { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - - MergePullRequestSpinner mergeId = (MergePullRequestSpinner) parent.getSelectedItem(); - Do = mergeId.getId(); - - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - - }); - - defaultMentionAdapter = new MentionArrayAdapter<>(this); - loadCollaboratorsList(); - - viewBinding.mergeDescription.setMentionAdapter(defaultMentionAdapter); - - if(!tinyDb.getString("issueTitle").isEmpty()) { - viewBinding.toolbarTitle.setText(tinyDb.getString("issueTitle")); - viewBinding.mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")"); + viewBinding.toolbarTitle.setText(tinyDB.getString("issueTitle")); + viewBinding.mergeTitle.setText(tinyDB.getString("issueTitle") + " (#" + tinyDB.getString("issueNumber") + ")"); } initCloseListener(); viewBinding.close.setOnClickListener(onClickListener); // if gitea version is greater/equal(1.12.0) than user installed version (installed.higherOrEqual(compareVer)) - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { + viewBinding.deleteBranch.setVisibility(View.VISIBLE); } - if(tinyDb.getString("prMergeable").equals("false")) { + if(tinyDB.getString("prMergeable").equals("false")) { + disableProcessButton(); viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE); } else { + viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE); } - if(tinyDb.getString("prIsFork").equals("true")) { + if(tinyDB.getString("prIsFork").equals("true")) { + viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE); } else { + viewBinding.deleteBranchForkInfo.setVisibility(View.GONE); } @@ -136,70 +120,25 @@ public class MergePullRequestActivity extends BaseActivity { private void setMergeAdapter() { - TinyDB tinyDb = new TinyDB(appCtx); - ArrayList mergeList = new ArrayList<>(); mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge))); mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase))); mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit))); // squash merge works only on gitea > v1.11.4 due to a bug - if(new Version(tinyDb.getString("giteaVersion")).higher("1.11.4")) { + if(new Version(tinyDB.getString("giteaVersion")).higher("1.11.4")) { + mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash))); } - ArrayAdapter adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.spinner_item, mergeList); - adapter.setDropDownViewResource(R.layout.spinner_dropdown_item); + ArrayAdapter adapter = new ArrayAdapter<>(MergePullRequestActivity.this, R.layout.list_spinner_items, mergeList); viewBinding.mergeSpinner.setAdapter(adapter); - } - - public void loadCollaboratorsList() { - - 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()); - } + viewBinding.mergeSpinner.setOnItemClickListener ((parent, view, position, id) -> { + Do = mergeList.get(position).getId(); }); + } private void initCloseListener() { @@ -207,12 +146,12 @@ public class MergePullRequestActivity extends BaseActivity { onClickListener = view -> finish(); } - private View.OnClickListener mergePullRequest = v -> processMergePullRequest(); + private final View.OnClickListener mergePullRequest = v -> processMergePullRequest(); private void processMergePullRequest() { - String mergePRDesc = viewBinding.mergeDescription.getText().toString(); - String mergePRTitle = viewBinding.mergeTitle.getText().toString(); + String mergePRDesc = Objects.requireNonNull(viewBinding.mergeDescription.getText()).toString(); + String mergePRTitle = Objects.requireNonNull(viewBinding.mergeTitle.getText()).toString(); boolean deleteBranch = viewBinding.deleteBranch.isChecked(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -221,30 +160,24 @@ public class MergePullRequestActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } - disableProcessButton(); - mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch); + if(Do == null) { + Toasty.error(ctx, getResources().getString(R.string.selectMergeStrategy)); + } + else { + + disableProcessButton(); + mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch); + } } private void mergeFunction(String Do, String mergePRDT, String mergeTitle, boolean deleteBranch) { - 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]; - final int prIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().mergePullRequest(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, prIndex, mergePR); + Call call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR); call.enqueue(new Callback() { @@ -255,9 +188,9 @@ public class MergePullRequestActivity extends BaseActivity { if(deleteBranch) { - if(tinyDb.getString("prIsFork").equals("true")) { + if(tinyDB.getString("prIsFork").equals("true")) { - String repoFullName = tinyDb.getString("prForkFullName"); + String repoFullName = tinyDB.getString("prForkFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; @@ -265,14 +198,13 @@ public class MergePullRequestActivity extends BaseActivity { deleteBranchFunction(repoOwner, repoName); Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); - tinyDb.putBoolean("prMerged", true); - tinyDb.putBoolean("resumePullRequests", true); + tinyDB.putBoolean("prMerged", true); + tinyDB.putBoolean("resumePullRequests", true); finish(); - } else { - String repoFullName = tinyDb.getString("repoFullName"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; @@ -280,20 +212,18 @@ public class MergePullRequestActivity extends BaseActivity { deleteBranchFunction(repoOwner, repoName); Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); - tinyDb.putBoolean("prMerged", true); - tinyDb.putBoolean("resumePullRequests", true); + tinyDB.putBoolean("prMerged", true); + tinyDB.putBoolean("resumePullRequests", true); finish(); - } } else { Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); - tinyDb.putBoolean("prMerged", true); - tinyDb.putBoolean("resumePullRequests", true); + tinyDB.putBoolean("prMerged", true); + tinyDB.putBoolean("resumePullRequests", true); finish(); - } } @@ -301,19 +231,21 @@ public class MergePullRequestActivity extends BaseActivity { enableProcessButton(); AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else if(response.code() == 404) { enableProcessButton(); Toasty.warning(ctx, getString(R.string.mergePR404ErrorMsg)); + } + else if(response.code() == 405) { + enableProcessButton(); + Toasty.warning(ctx, getString(R.string.mergeNotAllowed));; } else { enableProcessButton(); Toasty.error(ctx, getString(R.string.genericError)); - } } @@ -331,17 +263,11 @@ public class MergePullRequestActivity extends BaseActivity { private void deleteBranchFunction(String repoOwner, String repoName) { - TinyDB tinyDb = new TinyDB(appCtx); - - String instanceUrl = tinyDb.getString("instanceUrl"); - String loginUid = tinyDb.getString("loginUid"); - String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - String branchName = tinyDb.getString("prHeadBranch"); + String branchName = tinyDB.getString("prHeadBranch"); Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .deleteBranch(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, branchName); + .getApiInterface(ctx) + .deleteBranch(Authorization.get(ctx), repoOwner, repoName, branchName); call.enqueue(new Callback() { @@ -351,9 +277,7 @@ public class MergePullRequestActivity extends BaseActivity { if(response.code() == 204) { Log.i("deleteBranch", "Branch deleted successfully"); - } - } @Override @@ -361,7 +285,6 @@ public class MergePullRequestActivity extends BaseActivity { Log.e("onFailure", t.toString()); enableProcessButton(); - } }); diff --git a/app/src/main/java/org/mian/gitnex/activities/OpenRepoInBrowserActivity.java b/app/src/main/java/org/mian/gitnex/activities/OpenRepoInBrowserActivity.java index 84748009..175b4aea 100644 --- a/app/src/main/java/org/mian/gitnex/activities/OpenRepoInBrowserActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/OpenRepoInBrowserActivity.java @@ -25,8 +25,9 @@ public class OpenRepoInBrowserActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + appCtx = getApplicationContext(); - TinyDB tinyDb = new TinyDB(appCtx); + TinyDB tinyDb = TinyDB.getInstance(appCtx); try { @@ -46,9 +47,9 @@ public class OpenRepoInBrowserActivity extends AppCompatActivity { } catch(URISyntaxException e) { + Toasty.error(appCtx, getString(R.string.genericError)); } - } } diff --git a/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java index b4af52e3..b5a711f1 100644 --- a/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationDetailActivity.java @@ -23,9 +23,9 @@ import org.mian.gitnex.R; import org.mian.gitnex.fragments.BottomSheetOrganizationFragment; import org.mian.gitnex.fragments.MembersByOrgFragment; import org.mian.gitnex.fragments.OrganizationInfoFragment; +import org.mian.gitnex.fragments.OrganizationLabelsFragment; import org.mian.gitnex.fragments.RepositoriesByOrgFragment; import org.mian.gitnex.fragments.TeamsByOrgFragment; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import java.util.Objects; import io.mikael.urlbuilder.UrlBuilder; @@ -36,10 +36,6 @@ import io.mikael.urlbuilder.UrlBuilder; public class OrganizationDetailActivity extends BaseActivity implements BottomSheetOrganizationFragment.BottomSheetListener { - final Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; - @Override protected int getLayoutResourceId(){ return R.layout.activity_org_detail; @@ -49,11 +45,8 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); - TinyDB tinyDb = new TinyDB(appCtx); - String orgName = tinyDb.getString("orgName"); + String orgName = tinyDB.getString("orgName"); Toolbar toolbar = findViewById(R.id.toolbar); TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); @@ -71,20 +64,20 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh Typeface myTypeface; - switch(tinyDb.getInt("customFontId", -1)) { + switch(tinyDB.getInt("customFontId", -1)) { case 0: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf"); break; - case 2: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf"); break; - default: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf"); break; - } toolbarTitle.setTypeface(myTypeface); @@ -92,12 +85,18 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); int tabsCount = vg.getChildCount(); + for (int j = 0; j < tabsCount; j++) { + ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); int tabChildCount = vgTab.getChildCount(); + for (int i = 0; i < tabChildCount; i++) { + View tabViewChild = vgTab.getChildAt(i); + if (tabViewChild instanceof TextView) { + ((TextView) tabViewChild).setTypeface(myTypeface); } } @@ -105,7 +104,6 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); - } @@ -122,18 +120,21 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh int id = item.getItemId(); - switch (id) { - case android.R.id.home: - finish(); - return true; - case R.id.repoMenu: - BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(); - bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } + if(id == android.R.id.home) { + finish(); + return true; + } + else if(id == R.id.repoMenu) { + + BottomSheetOrganizationFragment bottomSheet = new BottomSheetOrganizationFragment(); + bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet"); + return true; + } + else { + + return super.onOptionsItemSelected(item); + } } @Override @@ -142,20 +143,27 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh switch (text) { case "repository": - tinyDb.putBoolean("organizationAction", true); + tinyDB.putBoolean("organizationAction", true); startActivity(new Intent(OrganizationDetailActivity.this, CreateRepoActivity.class)); break; + case "label": + + Intent intent = new Intent(ctx, CreateLabelActivity.class); + intent.putExtra("orgName", getIntent().getStringExtra("orgName")); + intent.putExtra("type", "org"); + ctx.startActivity(intent); + break; case "team": startActivity(new Intent(OrganizationDetailActivity.this, CreateTeamByOrgActivity.class)); break; case "copyOrgUrl": - String url = UrlBuilder.fromString(tinyDb.getString("instanceUrl")) + String url = UrlBuilder.fromString(tinyDB.getString("instanceUrl")) .withPath("/") .toString(); ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("orgUrl", url + tinyDb.getString("orgName")); + ClipData clip = ClipData.newPlainText("orgUrl", url + tinyDB.getString("orgName")); assert clipboard != null; clipboard.setPrimaryClip(clip); Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); @@ -175,25 +183,34 @@ public class OrganizationDetailActivity extends BaseActivity implements BottomSh String orgName; if(getIntent().getStringExtra("orgName") != null || !Objects.equals(getIntent().getStringExtra("orgName"), "")) { + orgName = getIntent().getStringExtra("orgName"); } else { - orgName = tinyDb.getString("orgName"); + + orgName = tinyDB.getString("orgName"); } Fragment fragment = null; switch (position) { + case 0: // info + return OrganizationInfoFragment.newInstance(orgName); case 1: // repos - return RepositoriesByOrgFragment.newInstance(orgName); - case 2: // teams + + return RepositoriesByOrgFragment.newInstance(orgName); + case 2: // labels + + return OrganizationLabelsFragment.newInstance(orgName); + case 3: // teams + return TeamsByOrgFragment.newInstance(orgName); - case 3: // members + case 4: // members + return MembersByOrgFragment.newInstance(orgName); } return fragment; - } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java index d48b25bf..0b457e92 100644 --- a/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/OrganizationTeamMembersActivity.java @@ -1,6 +1,5 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.Menu; @@ -33,9 +32,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot private GridView mGridView; private ProgressBar progressBar; - final Context ctx = this; - private Context appCtx; - private String teamId; @Override @@ -47,15 +43,10 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - 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"); - ImageView closeActivity = findViewById(R.id.close); TextView toolbarTitle = findViewById(R.id.toolbar_title); noDataMembers = findViewById(R.id.noDataMembers); @@ -66,52 +57,55 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot closeActivity.setOnClickListener(onClickListener); if(getIntent().getStringExtra("teamTitle") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamTitle")).equals("")) { - toolbarTitle.setText(getIntent().getStringExtra("teamTitle")); + + toolbarTitle.setText(getIntent().getStringExtra("teamTitle")); } else { - toolbarTitle.setText(R.string.orgTeamMembers); + + toolbarTitle.setText(R.string.orgTeamMembers); } if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){ - teamId = getIntent().getStringExtra("teamId"); + + teamId = getIntent().getStringExtra("teamId"); } else { - teamId = "0"; + + teamId = "0"; } assert teamId != null; - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId)); - + fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId)); } @Override public void onResume() { super.onResume(); - 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"); + TinyDB tinyDb = TinyDB.getInstance(appCtx); if(tinyDb.getBoolean("teamActionFlag")) { - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), Integer.parseInt(teamId)); + + fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId)); tinyDb.putBoolean("teamActionFlag", false); } - } - private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) { + private void fetchDataAsync(String instanceToken, int teamId) { TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class); - teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId, ctx).observe(this, teamMembersListMain -> { + teamMembersModel.getMembersByOrgList(instanceToken, teamId, ctx).observe(this, teamMembersListMain -> { adapter = new TeamMembersByOrgAdapter(ctx, teamMembersListMain); + if(adapter.getCount() > 0) { + mGridView.setAdapter(adapter); noDataMembers.setVisibility(View.GONE); } else { + adapter.notifyDataSetChanged(); mGridView.setAdapter(adapter); noDataMembers.setVisibility(View.VISIBLE); @@ -119,7 +113,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot progressBar.setVisibility(View.GONE); }); - } @Override @@ -128,7 +121,6 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.generic_nav_dotted_menu, menu); return true; - } @Override @@ -136,31 +128,32 @@ public class OrganizationTeamMembersActivity extends BaseActivity implements Bot int id = item.getItemId(); - switch(id) { - case android.R.id.home: - finish(); - return true; - case R.id.genericMenu: - BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment(); - bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } + if(id == android.R.id.home) { + finish(); + return true; + } + else if(id == R.id.genericMenu) { + + BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment(); + bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet"); + return true; + } + else { + + return super.onOptionsItemSelected(item); + } } @Override public void onButtonClicked(String text) { - TinyDB tinyDb = new TinyDB(appCtx); - if("newMember".equals(text)) { + Intent intent = new Intent(OrganizationTeamMembersActivity.this, AddNewTeamMemberActivity.class); intent.putExtra("teamId", teamId); startActivity(intent); } - } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java b/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java index 86d1b515..f38232b1 100644 --- a/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java @@ -33,8 +33,6 @@ public class ProfileEmailActivity extends BaseActivity { private View.OnClickListener onClickListener; private EditText userEmail; - final Context ctx = this; - private Context appCtx; private Button addEmailButton; @Override @@ -46,7 +44,6 @@ public class ProfileEmailActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); @@ -73,19 +70,11 @@ public class ProfileEmailActivity extends BaseActivity { } - private View.OnClickListener addEmailListener = new View.OnClickListener() { - public void onClick(View v) { - processAddNewEmail(); - } - }; + private final View.OnClickListener addEmailListener = v -> processAddNewEmail(); private void processAddNewEmail() { boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - 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 newUserEmail = userEmail.getText().toString().trim(); @@ -93,39 +82,34 @@ public class ProfileEmailActivity extends BaseActivity { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; - } if(newUserEmail.equals("")) { Toasty.error(ctx, getString(R.string.emailErrorEmpty)); return; - } else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { Toasty.warning(ctx, getString(R.string.emailErrorInvalid)); return; - } List newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(","))); disableProcessButton(); - addNewEmail(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), newEmailList); - + addNewEmail(Authorization.get(ctx), newEmailList); } - private void addNewEmail(final String instanceUrl, final String token, List newUserEmail) { + private void addNewEmail(final String token, List newUserEmail) { AddEmail addEmailFunc = new AddEmail(newUserEmail); - final TinyDB tinyDb = new TinyDB(appCtx); + final TinyDB tinyDb = TinyDB.getInstance(appCtx); Call call; call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(appCtx) .addNewEmail(token, addEmailFunc); call.enqueue(new Callback() { @@ -139,7 +123,6 @@ public class ProfileEmailActivity extends BaseActivity { tinyDb.putBoolean("emailsRefresh", true); enableProcessButton(); finish(); - } else if(response.code() == 401) { @@ -148,37 +131,32 @@ public class ProfileEmailActivity extends BaseActivity { getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - } else if(response.code() == 403) { enableProcessButton(); Toasty.error(ctx, ctx.getString(R.string.authorizeError)); - } else if(response.code() == 404) { enableProcessButton(); Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); - } else if(response.code() == 422) { enableProcessButton(); Toasty.warning(ctx, ctx.getString(R.string.emailErrorInUse)); - } else { enableProcessButton(); Toasty.error(ctx, getString(R.string.labelGeneralError)); - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e("onFailure", t.toString()); enableProcessButton(); } diff --git a/app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java deleted file mode 100644 index a7b6fd79..00000000 --- a/app/src/main/java/org/mian/gitnex/activities/ReplyToIssueActivity.java +++ /dev/null @@ -1,430 +0,0 @@ -package org.mian.gitnex.activities; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -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.IssueActions; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.database.api.DraftsApi; -import org.mian.gitnex.helpers.AlertDialogs; -import org.mian.gitnex.helpers.AppUtil; -import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.models.Collaborators; -import org.mian.gitnex.models.Issues; -import java.util.List; -import java.util.Objects; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; - -/** - * Author M M Arif - */ - -public class ReplyToIssueActivity extends BaseActivity { - - public ImageView closeActivity; - private View.OnClickListener onClickListener; - - final Context ctx = this; - private Context appCtx; - - private TextView draftSaved; - private SocialAutoCompleteTextView addComment; - private ArrayAdapter defaultMentionAdapter; - private Button replyButton; - private String TAG = StaticGlobalVariables.replyToIssueActivity; - private long draftIdOnCreate; - - @Override - protected int getLayoutResourceId(){ - return R.layout.activity_reply_to_issue; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - - boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - TinyDB tinyDb = new TinyDB(appCtx); - - draftSaved = findViewById(R.id.draftSaved); - addComment = findViewById(R.id.addComment); - addComment.setShowSoftInputOnFocus(true); - - defaultMentionAdapter = new MentionArrayAdapter<>(ctx); - loadCollaboratorsList(); - - addComment.setMentionAdapter(defaultMentionAdapter); - - closeActivity = findViewById(R.id.close); - TextView toolbar_title = findViewById(R.id.toolbar_title); - - addComment.requestFocus(); - assert imm != null; - imm.showSoftInput(addComment, InputMethodManager.SHOW_IMPLICIT); - - if(!tinyDb.getString("issueTitle").isEmpty()) { - toolbar_title.setText(tinyDb.getString("issueTitle")); - } - - initCloseListener(); - closeActivity.setOnClickListener(onClickListener); - - if(getIntent().getStringExtra("draftId") != null) { - - draftIdOnCreate = Long.parseLong(Objects.requireNonNull(getIntent().getStringExtra("draftId"))); - } - else { - - if(getIntent().getStringExtra("commentBody") != null) { - draftIdOnCreate = returnDraftId(getIntent().getStringExtra("commentBody")); - } - else { - draftIdOnCreate = returnDraftId(""); - } - } - - replyButton = findViewById(R.id.replyButton); - - if(getIntent().getStringExtra("commentBody") != null) { - - addComment.setText(getIntent().getStringExtra("commentBody")); - - if(getIntent().getBooleanExtra("cursorToEnd", false)) { - addComment.setSelection(addComment.length()); - } - - } - - if(getIntent().getStringExtra("draftTitle") != null) { - - toolbar_title.setText(getIntent().getStringExtra("draftTitle")); - - } - - if(getIntent().getStringExtra("commentAction") != null && Objects.equals(getIntent().getStringExtra("commentAction"), "edit") && !Objects.equals(getIntent().getStringExtra("commentId"), "new")) { - - final String commentId = getIntent().getStringExtra("commentId"); - - toolbar_title.setText(getResources().getString(R.string.editCommentTitle)); - replyButton.setText(getResources().getString(R.string.editCommentButtonText)); - - addComment.addTextChangedListener(new TextWatcher() { - - public void afterTextChanged(Editable s) { - - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - public void onTextChanged(CharSequence s, int start, int before, int count) { - - saveDraft(addComment.getText().toString(), commentId, draftIdOnCreate); - draftSaved.setVisibility(View.VISIBLE); - - } - - }); - - replyButton.setOnClickListener(v -> { - - disableProcessButton(); - assert commentId != null; - IssueActions.editIssueComment(ctx, Integer.parseInt(commentId), addComment.getText().toString(), draftIdOnCreate); - - }); - - return; - - } - - addComment.addTextChangedListener(new TextWatcher() { - - public void afterTextChanged(Editable s) { - - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - public void onTextChanged(CharSequence s, int start, int before, int count) { - - saveDraft(addComment.getText().toString(), "new", draftIdOnCreate); - draftSaved.setVisibility(View.VISIBLE); - - } - - }); - - if(!connToInternet) { - - disableProcessButton(); - - } - else { - - replyButton.setOnClickListener(replyToIssue); - - } - - } - - private void saveDraft(String draftText, String commentId, long draftIdOnCreate) { - - TinyDB tinyDb = new TinyDB(getApplicationContext()); - - int repositoryId = (int) tinyDb.getLong("repositoryId", 0); - int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId"); - int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber")); - - DraftsApi draftsApi = new DraftsApi(appCtx); - - if(draftIdOnCreate == 0) { - - draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment, commentId); - } - else { - - DraftsApi.updateDraft(draftText, (int) draftIdOnCreate, commentId); //updateDraftByIssueIdAsyncTask(draftText, issueNumber, repositoryId, commentId); - } - } - - private long returnDraftId(String draftText) { - - TinyDB tinyDb = new TinyDB(getApplicationContext()); - - int repositoryId = (int) tinyDb.getLong("repositoryId", 0); - int currentActiveAccountId = tinyDb.getInt("currentActiveAccountId"); - int issueNumber = Integer.parseInt(tinyDb.getString("issueNumber")); - - DraftsApi draftsApi = new DraftsApi(appCtx); - - return draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, draftText, StaticGlobalVariables.draftTypeComment, ""); - - } - - public void loadCollaboratorsList() { - - 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(TAG, String.valueOf(response.code())); - - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - - Log.e(TAG, t.toString()); - } - - }); - } - - private void initCloseListener() { - - onClickListener = view -> finish(); - } - - private View.OnClickListener replyToIssue = v -> processNewCommentReply(); - - private void processNewCommentReply() { - - String newReplyDT = addComment.getText().toString(); - boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - - if(!connToInternet) { - - Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); - return; - - } - - if(newReplyDT.equals("")) { - - Toasty.error(ctx, getString(R.string.commentEmptyError)); - - } - else { - - disableProcessButton(); - replyComment(newReplyDT); - - } - - } - - private void replyComment(String newReplyDT) { - - 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]; - final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber")); - - Issues issueComment = new Issues(newReplyDT); - - Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .replyCommentToIssue(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment); - - call.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - - if(response.code() == 201) { - - Toasty.success(ctx, getString(R.string.commentSuccess)); - tinyDb.putBoolean("commentPosted", true); - tinyDb.putBoolean("resumeIssues", true); - tinyDb.putBoolean("resumePullRequests", true); - - // delete draft comment - if(tinyDb.getBoolean("draftsCommentsDeletionEnabled")) { - - DraftsApi draftsApi = new DraftsApi(appCtx); - draftsApi.deleteSingleDraft((int) draftIdOnCreate); - } - - finish(); - - } - else if(response.code() == 401) { - - enableProcessButton(); - AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), - getResources().getString(R.string.alertDialogTokenRevokedMessage), - getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), - getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); - - } - else { - - enableProcessButton(); - Toasty.error(ctx, getString(R.string.commentError)); - - } - - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - - Log.e(TAG, t.toString()); - enableProcessButton(); - } - }); - - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.reply_to_issue, menu); - - return super.onCreateOptionsMenu(menu); - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - switch(item.getItemId()) { - - case R.id.replyToIssueMenu: - Intent fragmentIntent = new Intent(ReplyToIssueActivity.this, MainActivity.class); - fragmentIntent.putExtra("launchFragment", "drafts"); - ReplyToIssueActivity.this.startActivity(fragmentIntent); - break; - - default: - return super.onOptionsItemSelected(item); - - } - - return true; - } - - private void disableProcessButton() { - - replyButton.setEnabled(false); - } - - private void enableProcessButton() { - - replyButton.setEnabled(true); - } - -} diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java index 80b00689..518a962f 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java @@ -42,7 +42,6 @@ import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.ReleasesFragment; import org.mian.gitnex.fragments.RepoInfoFragment; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import org.mian.gitnex.models.Branches; @@ -71,12 +70,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone; private FragmentRefreshListenerFiles fragmentRefreshListenerFiles; - private final Context ctx = this; - private Context appCtx; - - private TinyDB tinyDB; - - private String instanceUrl; private String loginUid; private String instanceToken; @@ -96,9 +89,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - tinyDB = new TinyDB(appCtx); String[] repoNameParts = tinyDB.getString("repoFullName").split("/"); repositoryOwner = repoNameParts[0]; @@ -113,7 +103,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF Objects.requireNonNull(getSupportActionBar()).setTitle(repositoryName); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - instanceUrl = tinyDB.getString("instanceUrl"); loginUid = tinyDB.getString("loginUid"); instanceToken = "token " + tinyDB.getString(loginUid + "-token"); @@ -126,17 +115,17 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF switch(tinyDB.getInt("customFontId", -1)) { case 0: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf"); break; - case 2: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf"); break; - default: + myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf"); break; - } toolbarTitle.setTypeface(myTypeface); @@ -156,6 +145,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF View tabViewChild = vgTab.getChildAt(i); if(tabViewChild instanceof TextView) { + ((TextView) tabViewChild).setTypeface(myTypeface); } } @@ -172,7 +162,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF tabsCount--; collaboratorTab.setVisibility(View.GONE); - } mViewPager = findViewById(R.id.container); @@ -198,7 +187,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF textViewBadgePull.setVisibility(View.GONE); textViewBadgeRelease.setVisibility(View.GONE); - getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); + getRepoInfo(Authorization.get(ctx), repositoryOwner, repositoryName); ColorStateList textColor = tabLayout.getTabTextColors(); // Issue count @@ -209,7 +198,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF assert tabOpenIssues != null; // FIXME This should be cleaned up TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText); openIssueTabView.setTextColor(textColor); - } // Pull request count @@ -220,7 +208,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF assert tabOpenPulls != null; // FIXME This should be cleaned up TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText); openPullTabView.setTextColor(textColor); - } // Release count @@ -233,14 +220,31 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF assert tabOpenRelease != null; // FIXME This should be cleaned up TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText); openReleaseTabView.setTextColor(textColor); - } } } - checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); - checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); + Intent mainIntent = getIntent(); + String goToSection = mainIntent.getStringExtra("goToSection"); + String goToSectionType = mainIntent.getStringExtra("goToSectionType"); + if(goToSection != null) { + + mainIntent.removeExtra("goToSection"); + mainIntent.removeExtra("goToSectionType"); + + if(goToSectionType.equals("issue")) { + + RepoDetailActivity.mViewPager.setCurrentItem(2); + } + else if(goToSectionType.equals("pull")) { + + RepoDetailActivity.mViewPager.setCurrentItem(3); + } + } + + checkRepositoryStarStatus(Authorization.get(ctx), repositoryOwner, repositoryName); + checkRepositoryWatchStatus(Authorization.get(ctx), repositoryOwner, repositoryName); } @Override @@ -250,9 +254,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF if(tinyDB.getBoolean("enableCounterIssueBadge")) { - getRepoInfo(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); + getRepoInfo(Authorization.get(ctx), repositoryOwner, repositoryName); } - } @Override @@ -261,7 +264,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.repo_dotted_menu, menu); return true; - } @Override @@ -318,106 +320,111 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF switch(text) { case "label": + startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class)); break; - case "newIssue": + startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class)); break; - case "newMilestone": + startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class)); break; - case "addCollaborator": + startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class)); break; - case "chooseBranch": + chooseBranch(); break; - case "createRelease": + startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class)); break; - case "openWebRepo": + Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(tinyDB.getString("repoHtmlUrl"))); startActivity(i); break; - case "shareRepo": + Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, tinyDB.getString("repoHtmlUrl")); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, tinyDB.getString("repoHtmlUrl")); startActivity(Intent.createChooser(sharingIntent, tinyDB.getString("repoHtmlUrl"))); break; - case "copyRepoUrl": + ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("repoUrl", tinyDB.getString("repoHtmlUrl")); assert clipboard != null; clipboard.setPrimaryClip(clip); Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); break; - case "newFile": + startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); break; - case "openIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("open"); } break; - case "closedIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("closed"); } break; - case "openPr": + if(getFragmentRefreshListenerPr() != null) { + getFragmentRefreshListenerPr().onRefresh("open"); } break; - case "closedPr": + if(getFragmentRefreshListenerPr() != null) { + getFragmentRefreshListenerPr().onRefresh("closed"); } break; - case "openMilestone": + if(getFragmentRefreshListenerMilestone() != null) { + getFragmentRefreshListenerMilestone().onRefresh("open"); } break; - case "closedMilestone": + if(getFragmentRefreshListenerMilestone() != null) { + getFragmentRefreshListenerMilestone().onRefresh("closed"); } break; - case "repoSettings": + startActivity(new Intent(RepoDetailActivity.this, RepositorySettingsActivity.class)); break; - case "newPullRequest": + startActivity(new Intent(RepoDetailActivity.this, CreatePullRequestActivity.class)); break; - } - } private void chooseBranch() { - Call> call = RetrofitClient.getInstance(instanceUrl, ctx) - .getApiInterface() + Call> call = RetrofitClient + .getApiInterface(ctx) .getBranches(instanceToken, repositoryOwner, repositoryName); call.enqueue(new Callback>() { @@ -451,7 +458,9 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF public void onClick(DialogInterface dialogInterface, int i) { tinyDB.putString("repoBranch", branchesList.get(i)); + if(getFragmentRefreshListenerFiles() != null) { + getFragmentRefreshListenerFiles().onRefresh(branchesList.get(i)); } dialogInterface.dismiss(); @@ -460,9 +469,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF pBuilder.setNeutralButton(R.string.cancelButton, null); pBuilder.create().show(); - } - } @Override @@ -490,37 +497,36 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF switch(position) { case 0: // Repository details + return RepoInfoFragment.newInstance(repositoryOwner, repositoryName); - case 1: // Files - return FilesFragment.newInstance(repositoryOwner, repositoryName, tinyDB.getString("repoBranch")); + return FilesFragment.newInstance(repositoryOwner, repositoryName, tinyDB.getString("repoBranch")); case 2: // Issues + fragment = new IssuesFragment(); break; - case 3: // Pull requests + fragment = new PullRequestsFragment(); break; - case 4: // Releases - return ReleasesFragment.newInstance(repositoryOwner, repositoryName); + return ReleasesFragment.newInstance(repositoryOwner, repositoryName); case 5: // Milestones + fragment = new MilestonesFragment(); break; - case 6: // Labels + return LabelsFragment.newInstance(repositoryOwner, repositoryName); - case 7: // Collaborators - return CollaboratorsFragment.newInstance(repositoryOwner, repositoryName); + return CollaboratorsFragment.newInstance(repositoryOwner, repositoryName); } assert fragment != null; return fragment; - } @Override @@ -528,12 +534,11 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF return tabsCount; } - } - private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) { + private void getRepoInfo(String token, final String owner, String repo) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserRepository(token, owner, repo); + Call call = RetrofitClient.getApiInterface(ctx).getUserRepository(token, owner, repo); call.enqueue(new Callback() { @Override @@ -544,6 +549,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF if(response.code() == 200) { if(tinyDB.getBoolean("enableCounterBadges")) { + assert repoInfo != null; if(repoInfo.getOpen_issues_count() != null) { @@ -570,7 +576,6 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF Log.e("onFailure", String.valueOf(response.code())); } - } @Override @@ -583,16 +588,15 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF } - private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + private void checkRepositoryStarStatus(String instanceToken, final String owner, String repo) { - Call call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo); + Call call = RetrofitClient.getApiInterface(ctx).checkRepoStarStatus(instanceToken, owner, repo); call.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { tinyDB.putInt("repositoryStarStatus", response.code()); - } @Override @@ -604,11 +608,11 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF } - private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + private void checkRepositoryWatchStatus(String instanceToken, final String owner, String repo) { Call call; - call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo); + call = RetrofitClient.getApiInterface(ctx).checkRepoWatchStatus(instanceToken, owner, repo); call.enqueue(new Callback() { @Override @@ -619,15 +623,14 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF assert response.body() != null; if(response.body().getSubscribed()) { + tinyDB.putBoolean("repositoryWatchStatus", true); } - } else { tinyDB.putBoolean("repositoryWatchStatus", false); } - } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java index 8771fc40..a639abb1 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java @@ -1,7 +1,6 @@ package org.mian.gitnex.activities; import android.annotation.SuppressLint; -import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -42,8 +41,6 @@ import retrofit2.Response; public class RepoForksActivity extends BaseActivity { - final Context ctx = this; - private Context appCtx; private View.OnClickListener onClickListener; private TextView noData; private ProgressBar progressBar; @@ -67,14 +64,11 @@ public class RepoForksActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - 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"); + TinyDB tinyDb = TinyDB.getInstance(appCtx); String repoFullNameForForks = getIntent().getStringExtra("repoFullNameForForks"); assert repoFullNameForForks != null; @@ -97,6 +91,7 @@ public class RepoForksActivity extends BaseActivity { // if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances) if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; } @@ -110,7 +105,7 @@ public class RepoForksActivity extends BaseActivity { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - loadInitial(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, pageSize, resultLimit); + loadInitial(Authorization.get(ctx), repoOwner, repoName, pageSize, resultLimit); adapter.notifyDataChanged(); }, 200)); @@ -121,25 +116,21 @@ public class RepoForksActivity extends BaseActivity { if(forksList.size() == resultLimit || pageSize == resultLimit) { int page = (forksList.size() + resultLimit) / resultLimit; - loadMore(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, page, resultLimit); - + loadMore(Authorization.get(ctx), repoOwner, repoName, page, resultLimit); } - })); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); recyclerView.setAdapter(adapter); - loadInitial(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, pageSize, resultLimit); - + loadInitial(Authorization.get(ctx), repoOwner, repoName, pageSize, resultLimit); } - private void loadInitial(String instanceUrl, String instanceToken, String repoOwner, String repoName, int pageSize, int resultLimit) { + private void loadInitial(String instanceToken, String repoOwner, String repoName, int pageSize, int resultLimit) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getRepositoryForks(instanceToken, repoOwner, repoName, pageSize, resultLimit); call.enqueue(new Callback>() { @@ -150,29 +141,27 @@ public class RepoForksActivity extends BaseActivity { if(response.isSuccessful()) { assert response.body() != null; + if(response.body().size() > 0) { forksList.clear(); forksList.addAll(response.body()); adapter.notifyDataChanged(); noData.setVisibility(View.GONE); - } else { + forksList.clear(); adapter.notifyDataChanged(); noData.setVisibility(View.VISIBLE); } progressBar.setVisibility(View.GONE); - } else { Log.e(TAG, String.valueOf(response.code())); - } - } @Override @@ -180,18 +169,16 @@ public class RepoForksActivity extends BaseActivity { Log.e(TAG, t.toString()); } - }); } - private void loadMore(String instanceUrl, String instanceToken, String repoOwner, String repoName, int page, int resultLimit) { + private void loadMore(String instanceToken, String repoOwner, String repoName, int page, int resultLimit) { progressLoadMore.setVisibility(View.VISIBLE); Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getRepositoryForks(instanceToken, repoOwner, repoName, page, resultLimit); call.enqueue(new Callback>() { @@ -205,37 +192,31 @@ public class RepoForksActivity extends BaseActivity { forksList.remove(forksList.size() - 1); List result = response.body(); - assert result != null; + if(result.size() > 0) { pageSize = result.size(); forksList.addAll(result); - } else { adapter.setMoreDataAvailable(false); - } adapter.notifyDataChanged(); progressLoadMore.setVisibility(View.GONE); - } else { Log.e(TAG, String.valueOf(response.code())); - } - } @Override public void onFailure(@NonNull Call> call, @NonNull Throwable t) { Log.e(TAG, t.toString()); - } }); @@ -270,7 +251,6 @@ public class RepoForksActivity extends BaseActivity { }); return super.onCreateOptionsMenu(menu); - } private void filter(String text) { @@ -278,7 +258,9 @@ public class RepoForksActivity extends BaseActivity { List arr = new ArrayList<>(); for(UserRepositories d : forksList) { + if(d.getName().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) { + arr.add(d); } } @@ -289,6 +271,7 @@ public class RepoForksActivity extends BaseActivity { private void initCloseListener() { onClickListener = view -> { + getIntent().removeExtra("repoFullNameForForks"); finish(); }; diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoStargazersActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoStargazersActivity.java index 6656c3ad..12459a6f 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoStargazersActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoStargazersActivity.java @@ -1,22 +1,16 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.GridView; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.Nullable; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import org.mian.gitnex.R; import org.mian.gitnex.adapters.RepoStargazersAdapter; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.viewmodels.RepoStargazersViewModel; -import java.util.List; /** * Author M M Arif @@ -30,9 +24,6 @@ public class RepoStargazersActivity extends BaseActivity { private GridView mGridView; private ProgressBar mProgressBar; - final Context ctx = this; - private Context appCtx; - @Override protected int getLayoutResourceId(){ return R.layout.activity_repo_stargazers; @@ -42,12 +33,6 @@ public class RepoStargazersActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - 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"); ImageView closeActivity = findViewById(R.id.close); TextView toolbarTitle = findViewById(R.id.toolbar_title); @@ -65,29 +50,30 @@ public class RepoStargazersActivity extends BaseActivity { toolbarTitle.setText(R.string.repoStargazersInMenu); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); - + fetchDataAsync(Authorization.get(ctx), repoOwner, repoName); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) { + private void fetchDataAsync(String instanceToken, String repoOwner, String repoName) { RepoStargazersViewModel repoStargazersModel = new ViewModelProvider(this).get(RepoStargazersViewModel.class); - repoStargazersModel.getRepoStargazers(instanceUrl, instanceToken, repoOwner, repoName, ctx).observe(this, new Observer>() { - @Override - public void onChanged(@Nullable List stargazersListMain) { - adapter = new RepoStargazersAdapter(ctx, stargazersListMain); - if(adapter.getCount() > 0) { - mGridView.setAdapter(adapter); - noDataStargazers.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mGridView.setAdapter(adapter); - noDataStargazers.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); + repoStargazersModel.getRepoStargazers(instanceToken, repoOwner, repoName, ctx).observe(this, stargazersListMain -> { + + adapter = new RepoStargazersAdapter(ctx, stargazersListMain); + + if(adapter.getCount() > 0) { + + mGridView.setAdapter(adapter); + noDataStargazers.setVisibility(View.GONE); } + else { + + adapter.notifyDataSetChanged(); + mGridView.setAdapter(adapter); + noDataStargazers.setVisibility(View.VISIBLE); + } + + mProgressBar.setVisibility(View.GONE); }); } diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoWatchersActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoWatchersActivity.java index 497d898e..2582e527 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoWatchersActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoWatchersActivity.java @@ -1,22 +1,16 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.GridView; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.Nullable; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import org.mian.gitnex.R; import org.mian.gitnex.adapters.RepoWatchersAdapter; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.viewmodels.RepoWatchersViewModel; -import java.util.List; /** * Author M M Arif @@ -30,9 +24,6 @@ public class RepoWatchersActivity extends BaseActivity { private GridView mGridView; private ProgressBar mProgressBar; - final Context ctx = this; - private Context appCtx; - @Override protected int getLayoutResourceId(){ return R.layout.activity_repo_watchers; @@ -42,12 +33,6 @@ public class RepoWatchersActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - 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"); ImageView closeActivity = findViewById(R.id.close); TextView toolbarTitle = findViewById(R.id.toolbar_title); @@ -65,29 +50,30 @@ public class RepoWatchersActivity extends BaseActivity { toolbarTitle.setText(R.string.repoWatchersInMenu); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName); - + fetchDataAsync(Authorization.get(ctx), repoOwner, repoName); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String repoOwner, String repoName) { + private void fetchDataAsync(String instanceToken, String repoOwner, String repoName) { RepoWatchersViewModel repoWatchersModel = new ViewModelProvider(this).get(RepoWatchersViewModel.class); - repoWatchersModel.getRepoWatchers(instanceUrl, instanceToken, repoOwner, repoName, ctx).observe(this, new Observer>() { - @Override - public void onChanged(@Nullable List watchersListMain) { - adapter = new RepoWatchersAdapter(ctx, watchersListMain); - if(adapter.getCount() > 0) { - mGridView.setAdapter(adapter); - noDataWatchers.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mGridView.setAdapter(adapter); - noDataWatchers.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); + repoWatchersModel.getRepoWatchers(instanceToken, repoOwner, repoName, ctx).observe(this, watchersListMain -> { + + adapter = new RepoWatchersAdapter(ctx, watchersListMain); + + if(adapter.getCount() > 0) { + + mGridView.setAdapter(adapter); + noDataWatchers.setVisibility(View.GONE); } + else { + + adapter.notifyDataSetChanged(); + mGridView.setAdapter(adapter); + noDataWatchers.setVisibility(View.VISIBLE); + } + + mProgressBar.setVisibility(View.GONE); }); } diff --git a/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java index e4c0ff96..42735f5a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepositorySettingsActivity.java @@ -1,7 +1,6 @@ package org.mian.gitnex.activities; import android.app.Dialog; -import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; @@ -18,7 +17,6 @@ import org.mian.gitnex.databinding.ActivityRepositorySettingsBinding; import org.mian.gitnex.databinding.CustomRepositoryDeleteDialogBinding; import org.mian.gitnex.databinding.CustomRepositoryEditPropertiesDialogBinding; import org.mian.gitnex.databinding.CustomRepositoryTransferDialogBinding; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import org.mian.gitnex.models.RepositoryTransfer; @@ -40,11 +38,7 @@ public class RepositorySettingsActivity extends BaseActivity { private Dialog dialogDeleteRepository; private Dialog dialogTransferRepository; private View.OnClickListener onClickListener; - private Context ctx = this; - private Context appCtx; - private TinyDB tinyDb; - private String instanceUrl; private String loginUid; private String instanceToken; @@ -60,20 +54,17 @@ public class RepositorySettingsActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - tinyDb = new TinyDB(appCtx); viewBinding = ActivityRepositorySettingsBinding.inflate(getLayoutInflater()); View view = viewBinding.getRoot(); setContentView(view); - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); + loginUid = tinyDB.getString("loginUid"); + String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); repositoryOwner = parts[0]; repositoryName = parts[1]; - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + instanceToken = "token " + tinyDB.getString(loginUid + "-token"); ImageView closeActivity = findViewById(R.id.close); @@ -81,23 +72,16 @@ public class RepositorySettingsActivity extends BaseActivity { closeActivity.setOnClickListener(onClickListener); // require gitea 1.12 or higher - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { + viewBinding.transferOwnerFrame.setVisibility(View.VISIBLE); } - viewBinding.editProperties.setOnClickListener(editProperties -> { - showRepositoryProperties(); - }); + viewBinding.editProperties.setOnClickListener(editProperties -> showRepositoryProperties()); - viewBinding.deleteRepository.setOnClickListener(deleteRepository -> { - showDeleteRepository(); - }); - - viewBinding.transferOwnerFrame.setOnClickListener(transferRepositoryOwnership -> { - showTransferRepository(); - }); + viewBinding.deleteRepository.setOnClickListener(deleteRepository -> showDeleteRepository()); + viewBinding.transferOwnerFrame.setOnClickListener(transferRepositoryOwnership -> showTransferRepository()); } private void showTransferRepository() { @@ -114,9 +98,7 @@ public class RepositorySettingsActivity extends BaseActivity { View view = transferRepoBinding.getRoot(); dialogTransferRepository.setContentView(view); - transferRepoBinding.cancel.setOnClickListener(editProperties -> { - dialogTransferRepository.dismiss(); - }); + transferRepoBinding.cancel.setOnClickListener(editProperties -> dialogTransferRepository.dismiss()); transferRepoBinding.transfer.setOnClickListener(deleteRepo -> { @@ -145,8 +127,7 @@ public class RepositorySettingsActivity extends BaseActivity { RepositoryTransfer repositoryTransfer = new RepositoryTransfer(newOwner); Call transferCall = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .transferRepository(instanceToken, repositoryOwner, repositoryName, repositoryTransfer); transferCall.enqueue(new Callback() { @@ -163,7 +144,7 @@ public class RepositorySettingsActivity extends BaseActivity { Toasty.success(ctx, getString(R.string.repoTransferSuccess)); finish(); - RepositoriesApi.deleteRepository((int) tinyDb.getLong("repositoryId", 0)); + RepositoriesApi.deleteRepository((int) tinyDB.getLong("repositoryId", 0)); Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class); RepositorySettingsActivity.this.startActivity(intent); } @@ -197,6 +178,7 @@ public class RepositorySettingsActivity extends BaseActivity { dialogDeleteRepository = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); if (dialogDeleteRepository.getWindow() != null) { + dialogDeleteRepository.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } @@ -205,9 +187,7 @@ public class RepositorySettingsActivity extends BaseActivity { View view = deleteRepoBinding.getRoot(); dialogDeleteRepository.setContentView(view); - deleteRepoBinding.cancel.setOnClickListener(editProperties -> { - dialogDeleteRepository.dismiss(); - }); + deleteRepoBinding.cancel.setOnClickListener(editProperties -> dialogDeleteRepository.dismiss()); deleteRepoBinding.delete.setOnClickListener(deleteRepo -> { @@ -227,8 +207,7 @@ public class RepositorySettingsActivity extends BaseActivity { private void deleteRepository() { Call deleteCall = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .deleteRepository(instanceToken, repositoryOwner, repositoryName); deleteCall.enqueue(new Callback() { @@ -245,7 +224,7 @@ public class RepositorySettingsActivity extends BaseActivity { Toasty.success(ctx, getString(R.string.repoDeletionSuccess)); finish(); - RepositoriesApi.deleteRepository((int) tinyDb.getLong("repositoryId", 0)); + RepositoriesApi.deleteRepository((int) tinyDB.getLong("repositoryId", 0)); Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class); RepositorySettingsActivity.this.startActivity(intent); } @@ -273,6 +252,7 @@ public class RepositorySettingsActivity extends BaseActivity { dialogProp = new Dialog(ctx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); if (dialogProp.getWindow() != null) { + dialogProp.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } @@ -281,13 +261,10 @@ public class RepositorySettingsActivity extends BaseActivity { View view = propBinding.getRoot(); dialogProp.setContentView(view); - propBinding.cancel.setOnClickListener(editProperties -> { - dialogProp.dismiss(); - }); + propBinding.cancel.setOnClickListener(editProperties -> dialogProp.dismiss()); Call call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getUserRepository(instanceToken, repositoryOwner, repositoryName); call.enqueue(new Callback() { @@ -314,19 +291,24 @@ public class RepositorySettingsActivity extends BaseActivity { propBinding.repoEnableIssues.setOnCheckedChangeListener((buttonView, isChecked) -> { if (isChecked) { + propBinding.repoEnableTimer.setVisibility(View.VISIBLE); } else { + propBinding.repoEnableTimer.setVisibility(View.GONE); } }); if(repoInfo.getInternal_tracker() != null) { + propBinding.repoEnableTimer.setChecked(repoInfo.getInternal_tracker().isEnable_time_tracker()); } else { + propBinding.repoEnableTimer.setVisibility(View.GONE); } + propBinding.repoEnableWiki.setChecked(repoInfo.isHas_wiki()); propBinding.repoEnablePr.setChecked(repoInfo.isHas_pull_requests()); propBinding.repoEnableMerge.setChecked(repoInfo.isAllow_merge_commits()); @@ -359,7 +341,6 @@ public class RepositorySettingsActivity extends BaseActivity { propBinding.repoEnableSquash.isChecked(), propBinding.repoEnableForceMerge.isChecked())); dialogProp.show(); - } private void saveRepositoryProperties(String repoName, String repoWebsite, String repoDescription, @@ -370,18 +351,20 @@ public class RepositorySettingsActivity extends BaseActivity { UserRepositories.internalTimeTrackerObject repoPropsTimeTracker = new UserRepositories.internalTimeTrackerObject(repoEnableTimer); UserRepositories repoProps; + if(!repoEnableIssues) { + repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoEnableMerge, repoEnableRebase, repoEnableSquash, repoEnableForceMerge); } else { + repoProps = new UserRepositories(repoName, repoWebsite, repoDescription, repoPrivate, repoAsTemplate, repoEnableIssues, repoEnableWiki, repoEnablePr, repoPropsTimeTracker, repoEnableMerge, repoEnableRebase, repoEnableSquash, repoEnableForceMerge); } Call propsCall = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .updateRepositoryProperties(instanceToken, repositoryOwner, repositoryName, repoProps); propsCall.enqueue(new Callback() { @@ -394,8 +377,8 @@ public class RepositorySettingsActivity extends BaseActivity { if (response.code() == 200) { - tinyDb.putBoolean("hasIssues", repoEnableIssues); - tinyDb.putBoolean("hasPullRequests", repoEnablePr); + tinyDB.putBoolean("hasIssues", repoEnableIssues); + tinyDB.putBoolean("hasPullRequests", repoEnablePr); dialogProp.dismiss(); Toasty.success(ctx, getString(R.string.repoPropertiesSaveSuccess)); @@ -403,10 +386,9 @@ public class RepositorySettingsActivity extends BaseActivity { if(!repositoryName.equals(repoName)) { finish(); - RepositoriesApi.updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDb.getLong("repositoryId", 0)); + RepositoriesApi.updateRepositoryOwnerAndName(repositoryOwner, repoName, (int) tinyDB.getLong("repositoryId", 0)); Intent intent = new Intent(RepositorySettingsActivity.this, MainActivity.class); RepositorySettingsActivity.this.startActivity(intent); - } } else { @@ -415,7 +397,6 @@ public class RepositorySettingsActivity extends BaseActivity { propBinding.processingRequest.setVisibility(View.GONE); Toasty.error(ctx, getString(R.string.genericError)); } - } @Override diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java index b7cf2c14..95b54ec1 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java @@ -1,17 +1,14 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.Switch; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; +import com.google.android.material.switchmaterial.SwitchMaterial; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.helpers.Version; /** * Author M M Arif @@ -19,23 +16,15 @@ import org.mian.gitnex.helpers.Version; public class SettingsAppearanceActivity extends BaseActivity { - private Context appCtx; private View.OnClickListener onClickListener; - private static String[] timeList = {"Pretty", "Normal"}; + private static final String[] timeList = {"Pretty", "Normal"}; private static int timeSelectedChoice = 0; - private static String[] codeBlockList = {"Green - Black", "White - Black", "Grey - Black", "White - Grey", "Dark - White"}; - private static int codeBlockSelectedChoice = 0; - - private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile", "Explore", "Drafts"}; - private static String[] homeScreenListNew = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile", "Explore", "Drafts", "Notifications"}; - private static int homeScreenSelectedChoice = 0; - - private static String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"}; + private static final String[] customFontList = {"Roboto", "Manrope", "Source Code Pro"}; private static int customFontSelectedChoice = 0; - private static String[] themeList = {"Dark", "Light", "Auto (Light / Dark)", "Retro", "Auto (Retro / Dark)"}; + private static final String[] themeList = {"Dark", "Light", "Auto (Light / Dark)", "Retro", "Auto (Retro / Dark)", "Pitch Black"}; private static int themeSelectedChoice = 0; @Override @@ -48,93 +37,59 @@ public class SettingsAppearanceActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - final TinyDB tinyDb = new TinyDB(appCtx); ImageView closeActivity = findViewById(R.id.close); final TextView tvDateTimeSelected = findViewById(R.id.tvDateTimeSelected); // setter for time - final TextView codeBlockSelected = findViewById(R.id.codeBlockSelected); // setter for code block - final TextView homeScreenSelected = findViewById(R.id.homeScreenSelected); // setter for home screen final TextView customFontSelected = findViewById(R.id.customFontSelected); // setter for custom font final TextView themeSelected = findViewById(R.id.themeSelected); // setter for theme LinearLayout timeFrame = findViewById(R.id.timeFrame); - LinearLayout codeBlockFrame = findViewById(R.id.codeBlockFrame); - LinearLayout homeScreenFrame = findViewById(R.id.homeScreenFrame); LinearLayout customFontFrame = findViewById(R.id.customFontFrame); LinearLayout themeFrame = findViewById(R.id.themeSelectionFrame); - Switch counterBadgesSwitch = findViewById(R.id.switchCounterBadge); + SwitchMaterial counterBadgesSwitch = findViewById(R.id.switchCounterBadge); initCloseListener(); closeActivity.setOnClickListener(onClickListener); - if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.3")) { + if(!tinyDB.getString("timeStr").isEmpty()) { - homeScreenList = homeScreenListNew; + tvDateTimeSelected.setText(tinyDB.getString("timeStr")); } - if(!tinyDb.getString("timeStr").isEmpty()) { - tvDateTimeSelected.setText(tinyDb.getString("timeStr")); + if(!tinyDB.getString("customFontStr").isEmpty()) { + + customFontSelected.setText(tinyDB.getString("customFontStr")); } - if(!tinyDb.getString("codeBlockStr").isEmpty()) { - codeBlockSelected.setText(tinyDb.getString("codeBlockStr")); - } + if(!tinyDB.getString("themeStr").isEmpty()) { - if(!tinyDb.getString("homeScreenStr").isEmpty()) { - homeScreenSelected.setText(tinyDb.getString("homeScreenStr")); - } - - if(!tinyDb.getString("customFontStr").isEmpty()) { - customFontSelected.setText(tinyDb.getString("customFontStr")); - } - - if(!tinyDb.getString("themeStr").isEmpty()) { - themeSelected.setText(tinyDb.getString("themeStr")); + themeSelected.setText(tinyDB.getString("themeStr")); } if(timeSelectedChoice == 0) { - timeSelectedChoice = tinyDb.getInt("timeId"); - } - if(codeBlockSelectedChoice == 0) { - codeBlockSelectedChoice = tinyDb.getInt("codeBlockId"); - } - - if(homeScreenSelectedChoice == 0) { - homeScreenSelectedChoice = tinyDb.getInt("homeScreenId"); + timeSelectedChoice = tinyDB.getInt("timeId"); } if(customFontSelectedChoice == 0) { - customFontSelectedChoice = tinyDb.getInt("customFontId", 1); + + customFontSelectedChoice = tinyDB.getInt("customFontId", 1); } if(themeSelectedChoice == 0) { - themeSelectedChoice = tinyDb.getInt("themeId"); + + themeSelectedChoice = tinyDB.getInt("themeId"); } - if(tinyDb.getBoolean("enableCounterBadges")) { - counterBadgesSwitch.setChecked(true); - } - else { - counterBadgesSwitch.setChecked(false); - } + counterBadgesSwitch.setChecked(tinyDB.getBoolean("enableCounterBadges")); // counter badge switcher counterBadgesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) { - tinyDb.putBoolean("enableCounterBadges", true); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - else { - tinyDb.putBoolean("enableCounterBadges", false); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - + tinyDB.putBoolean("enableCounterBadges", isChecked); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); }); // theme selection dialog @@ -143,31 +98,24 @@ public class SettingsAppearanceActivity extends BaseActivity { AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this); tsBuilder.setTitle(getResources().getString(R.string.themeSelectorDialogTitle)); - if(themeSelectedChoice != -1) { - tsBuilder.setCancelable(true); - } - else { - tsBuilder.setCancelable(false); - } + tsBuilder.setCancelable(themeSelectedChoice != -1); tsBuilder.setSingleChoiceItems(themeList, themeSelectedChoice, (dialogInterfaceTheme, i) -> { themeSelectedChoice = i; themeSelected.setText(themeList[i]); - tinyDb.putString("themeStr", themeList[i]); - tinyDb.putInt("themeId", i); + tinyDB.putString("themeStr", themeList[i]); + tinyDB.putInt("themeId", i); - tinyDb.putBoolean("refreshParent", true); + tinyDB.putBoolean("refreshParent", true); this.recreate(); this.overridePendingTransition(0, 0); dialogInterfaceTheme.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); AlertDialog cfDialog = tsBuilder.create(); cfDialog.show(); - }); // custom font dialog @@ -176,114 +124,24 @@ public class SettingsAppearanceActivity extends BaseActivity { AlertDialog.Builder cfBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this); cfBuilder.setTitle(R.string.settingsCustomFontSelectorDialogTitle); - if(customFontSelectedChoice != -1) { - cfBuilder.setCancelable(true); - } - else { - cfBuilder.setCancelable(false); - } + cfBuilder.setCancelable(customFontSelectedChoice != -1); cfBuilder.setSingleChoiceItems(customFontList, customFontSelectedChoice, (dialogInterfaceCustomFont, i) -> { customFontSelectedChoice = i; customFontSelected.setText(customFontList[i]); - tinyDb.putString("customFontStr", customFontList[i]); - tinyDb.putInt("customFontId", i); + tinyDB.putString("customFontStr", customFontList[i]); + tinyDB.putInt("customFontId", i); - tinyDb.putBoolean("refreshParent", true); + tinyDB.putBoolean("refreshParent", true); this.recreate(); this.overridePendingTransition(0, 0); dialogInterfaceCustomFont.dismiss(); Toasty.success(appCtx, appCtx.getResources().getString(R.string.settingsSave)); - }); AlertDialog cfDialog = cfBuilder.create(); cfDialog.show(); - - }); - - // home screen dialog - homeScreenFrame.setOnClickListener(view -> { - - AlertDialog.Builder hsBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this); - - hsBuilder.setTitle(R.string.settingsHomeScreenSelectorDialogTitle); - if(homeScreenSelectedChoice != -1) { - hsBuilder.setCancelable(true); - } - else { - hsBuilder.setCancelable(false); - } - - hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> { - - homeScreenSelectedChoice = i; - homeScreenSelected.setText(homeScreenList[i]); - tinyDb.putString("homeScreenStr", homeScreenList[i]); - tinyDb.putInt("homeScreenId", i); - - dialogInterfaceHomeScreen.dismiss(); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - - }); - - AlertDialog hsDialog = hsBuilder.create(); - hsDialog.show(); - - }); - - // code block dialog - codeBlockFrame.setOnClickListener(view -> { - - AlertDialog.Builder cBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this); - - cBuilder.setTitle(R.string.settingsCodeBlockSelectorDialogTitle); - if(codeBlockSelectedChoice != -1) { - cBuilder.setCancelable(true); - } - else { - cBuilder.setCancelable(false); - } - - cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, (dialogInterfaceCodeBlock, i) -> { - - codeBlockSelectedChoice = i; - codeBlockSelected.setText(codeBlockList[i]); - tinyDb.putString("codeBlockStr", codeBlockList[i]); - tinyDb.putInt("codeBlockId", i); - - switch(codeBlockList[i]) { - case "White - Black": - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); - break; - case "Grey - Black": - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorAccent)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); - break; - case "White - Grey": - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorWhite)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent)); - break; - case "Dark - White": - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorWhite)); - break; - default: - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); - break; - } - - dialogInterfaceCodeBlock.dismiss(); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - - }); - - AlertDialog cDialog = cBuilder.create(); - cDialog.show(); - }); // time and date dialog @@ -292,36 +150,30 @@ public class SettingsAppearanceActivity extends BaseActivity { AlertDialog.Builder tBuilder = new AlertDialog.Builder(SettingsAppearanceActivity.this); tBuilder.setTitle(R.string.settingsTimeSelectorDialogTitle); - if(timeSelectedChoice != -1) { - tBuilder.setCancelable(true); - } - else { - tBuilder.setCancelable(false); - } + tBuilder.setCancelable(timeSelectedChoice != -1); tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, (dialogInterfaceTime, i) -> { timeSelectedChoice = i; tvDateTimeSelected.setText(timeList[i]); - tinyDb.putString("timeStr", timeList[i]); - tinyDb.putInt("timeId", i); + tinyDB.putString("timeStr", timeList[i]); + tinyDB.putInt("timeId", i); if("Normal".equals(timeList[i])) { - tinyDb.putString("dateFormat", "normal"); + + tinyDB.putString("dateFormat", "normal"); } else { - tinyDb.putString("dateFormat", "pretty"); + + tinyDB.putString("dateFormat", "pretty"); } dialogInterfaceTime.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); AlertDialog tDialog = tBuilder.create(); tDialog.show(); - - }); } diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsDraftsActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsDraftsActivity.java index c3c4239d..f7891a38 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsDraftsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsDraftsActivity.java @@ -1,13 +1,11 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.ImageView; -import android.widget.Switch; +import com.google.android.material.switchmaterial.SwitchMaterial; import org.mian.gitnex.R; import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.helpers.TinyDB; /** * Author M M Arif @@ -15,7 +13,6 @@ import org.mian.gitnex.helpers.TinyDB; public class SettingsDraftsActivity extends BaseActivity { - private Context appCtx; private View.OnClickListener onClickListener; @Override @@ -28,36 +25,21 @@ public class SettingsDraftsActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - TinyDB tinyDb = new TinyDB(appCtx); ImageView closeActivity = findViewById(R.id.close); initCloseListener(); closeActivity.setOnClickListener(onClickListener); - Switch commentsDeletionSwitch = findViewById(R.id.commentsDeletionSwitch); + SwitchMaterial commentsDeletionSwitch = findViewById(R.id.commentsDeletionSwitch); - if(tinyDb.getBoolean("draftsCommentsDeletionEnabled")) { - commentsDeletionSwitch.setChecked(true); - } - else { - commentsDeletionSwitch.setChecked(false); - } + commentsDeletionSwitch.setChecked(tinyDB.getBoolean("draftsCommentsDeletionEnabled")); // delete comments on submit switcher commentsDeletionSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(isChecked) { - tinyDb.putBoolean("draftsCommentsDeletionEnabled", true); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - else { - tinyDb.putBoolean("draftsCommentsDeletionEnabled", false); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - + tinyDB.putBoolean("draftsCommentsDeletionEnabled", isChecked); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); }); } diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java index 27544cc7..b0b60a65 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java @@ -1,15 +1,13 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.Switch; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; +import com.google.android.material.switchmaterial.SwitchMaterial; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; /** @@ -18,10 +16,9 @@ import org.mian.gitnex.helpers.Toasty; public class SettingsFileViewerActivity extends BaseActivity { - private Context appCtx; private View.OnClickListener onClickListener; - private static String[] fileViewerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"}; + private static final String[] fileViewerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"}; private static int fileViewerSourceCodeThemesSelectedChoice = 0; @Override @@ -34,9 +31,6 @@ public class SettingsFileViewerActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - final TinyDB tinyDb = new TinyDB(appCtx); ImageView closeActivity = findViewById(R.id.close); @@ -47,22 +41,17 @@ public class SettingsFileViewerActivity extends BaseActivity { LinearLayout sourceCodeThemeFrame = findViewById(R.id.sourceCodeThemeFrame); - Switch pdfModeSwitch = findViewById(R.id.switchPdfMode); + SwitchMaterial pdfModeSwitch = findViewById(R.id.switchPdfMode); - if(!tinyDb.getString("fileviewerSourceCodeThemeStr").isEmpty()) { - fileViewerSourceCodeThemesSelected.setText(tinyDb.getString("fileviewerSourceCodeThemeStr")); + if(!tinyDB.getString("fileviewerSourceCodeThemeStr").isEmpty()) { + fileViewerSourceCodeThemesSelected.setText(tinyDB.getString("fileviewerSourceCodeThemeStr")); } if(fileViewerSourceCodeThemesSelectedChoice == 0) { - fileViewerSourceCodeThemesSelectedChoice = tinyDb.getInt("fileviewerThemeId"); + fileViewerSourceCodeThemesSelectedChoice = tinyDB.getInt("fileviewerThemeId"); } - if(tinyDb.getBoolean("enablePdfMode")) { - pdfModeSwitch.setChecked(true); - } - else { - pdfModeSwitch.setChecked(false); - } + pdfModeSwitch.setChecked(tinyDB.getBoolean("enablePdfMode")); // fileviewer srouce code theme selection dialog sourceCodeThemeFrame.setOnClickListener(view -> { @@ -70,19 +59,14 @@ public class SettingsFileViewerActivity extends BaseActivity { AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this); fvtsBuilder.setTitle(R.string.fileviewerSourceCodeThemeSelectorDialogTitle); - if(fileViewerSourceCodeThemesSelectedChoice != -1) { - fvtsBuilder.setCancelable(true); - } - else { - fvtsBuilder.setCancelable(false); - } + fvtsBuilder.setCancelable(fileViewerSourceCodeThemesSelectedChoice != -1); fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> { fileViewerSourceCodeThemesSelectedChoice = i; fileViewerSourceCodeThemesSelected.setText(fileViewerSourceCodeThemesList[i]); - tinyDb.putString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[i]); - tinyDb.putInt("fileviewerSourceCodeThemeId", i); + tinyDB.putString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[i]); + tinyDB.putInt("fileviewerSourceCodeThemeId", i); dialogInterfaceTheme.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); @@ -91,25 +75,15 @@ public class SettingsFileViewerActivity extends BaseActivity { AlertDialog cfDialog = fvtsBuilder.create(); cfDialog.show(); - }); // pdf night mode switcher pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(isChecked) { - tinyDb.putBoolean("enablePdfMode", true); - tinyDb.putString("enablePdfModeInit", "yes"); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - else { - tinyDb.putBoolean("enablePdfMode", false); - tinyDb.putString("enablePdfModeInit", "yes"); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - + tinyDB.putBoolean("enablePdfMode", isChecked); + tinyDB.putString("enablePdfModeInit", "yes"); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); }); - } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java new file mode 100644 index 00000000..1dc290ec --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java @@ -0,0 +1,176 @@ +package org.mian.gitnex.activities; + +import android.os.Bundle; +import android.view.View; +import androidx.appcompat.app.AlertDialog; +import org.mian.gitnex.R; +import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.Version; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Author M M Arif + */ + +public class SettingsGeneralActivity extends BaseActivity { + + private ActivitySettingsGeneralBinding viewBinding; + private View.OnClickListener onClickListener; + + private List homeScreenList; + private static int homeScreenSelectedChoice = 0; + + private List defaultScreen; + private static int defaultLinkHandlerScreenSelectedChoice = 0; + + @Override + protected int getLayoutResourceId() { + + return R.layout.activity_settings_general; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + + viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); + + initCloseListener(); + viewBinding.close.setOnClickListener(onClickListener); + + // home screen + String[] homeDefaultScreen_ = {getResources().getString(R.string.pageTitleMyRepos), getResources().getString(R.string.pageTitleStarredRepos), getResources().getString(R.string.pageTitleOrganizations), + getResources().getString(R.string.pageTitleRepositories), getResources().getString(R.string.pageTitleProfile), getResources().getString(R.string.pageTitleExplore), + getResources().getString(R.string.titleDrafts)}; + + String[] homeDefaultScreenNew = {getResources().getString(R.string.pageTitleMyRepos), getResources().getString(R.string.pageTitleStarredRepos), getResources().getString(R.string.pageTitleOrganizations), + getResources().getString(R.string.pageTitleRepositories), getResources().getString(R.string.pageTitleProfile), getResources().getString(R.string.pageTitleExplore), + getResources().getString(R.string.titleDrafts), getResources().getString(R.string.pageTitleNotifications)}; + + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) { + + homeDefaultScreen_ = homeDefaultScreenNew; + } + + homeScreenList = new ArrayList<>(Arrays.asList(homeDefaultScreen_)); + String[] homeScreenArray = new String[homeScreenList.size()]; + homeScreenList.toArray(homeScreenArray); + + if(homeScreenSelectedChoice == 0) { + + homeScreenSelectedChoice = tinyDB.getInt("homeScreenId"); + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleMyRepos)); + } + + if(homeScreenSelectedChoice == 1) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleStarredRepos)); + } + else if(homeScreenSelectedChoice == 2) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleOrganizations)); + } + else if(homeScreenSelectedChoice == 3) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleRepositories)); + } + else if(homeScreenSelectedChoice == 4) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleProfile)); + } + else if(homeScreenSelectedChoice == 5) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleExplore)); + } + else if(homeScreenSelectedChoice == 6) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.titleDrafts)); + } + else if(homeScreenSelectedChoice == 7) { + + viewBinding.homeScreenSelected.setText(getResources().getString(R.string.pageTitleNotifications)); + } + + viewBinding.homeScreenFrame.setOnClickListener(setDefaultHomeScreen -> { + + AlertDialog.Builder hsBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this); + + hsBuilder.setTitle(R.string.settingsHomeScreenSelectorDialogTitle); + hsBuilder.setCancelable(homeScreenSelectedChoice != -1); + + hsBuilder.setSingleChoiceItems(homeScreenArray, homeScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> { + + homeScreenSelectedChoice = i; + viewBinding.homeScreenSelected.setText(homeScreenArray[i]); + tinyDB.putInt("homeScreenId", i); + + dialogInterfaceHomeScreen.dismiss(); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); + }); + + AlertDialog hsDialog = hsBuilder.create(); + hsDialog.show(); + }); + // home screen + + // link handler + String[] defaultScreen_ = {getResources().getString(R.string.generalDeepLinkSelectedText), getResources().getString(R.string.navRepos), getResources().getString(R.string.navOrgs), getResources().getString(R.string.pageTitleNotifications), getResources().getString(R.string.navExplore)}; + defaultScreen = new ArrayList<>(Arrays.asList(defaultScreen_)); + + String[] linksArray = new String[defaultScreen.size()]; + defaultScreen.toArray(linksArray); + + if(defaultLinkHandlerScreenSelectedChoice == 0) { + + defaultLinkHandlerScreenSelectedChoice = tinyDB.getInt("defaultScreenId"); + viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.generalDeepLinkSelectedText)); + } + + if(defaultLinkHandlerScreenSelectedChoice == 1) { + + viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navRepos)); + } + else if(defaultLinkHandlerScreenSelectedChoice == 2) { + + viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navOrgs)); + } + else if(defaultLinkHandlerScreenSelectedChoice == 3) { + + viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.pageTitleNotifications)); + } + else if(defaultLinkHandlerScreenSelectedChoice == 4) { + + viewBinding.generalDeepLinkSelected.setText(getResources().getString(R.string.navExplore)); + } + + viewBinding.setDefaultLinkHandler.setOnClickListener(setDefaultLinkHandler -> { + + AlertDialog.Builder dlBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this); + dlBuilder.setTitle(R.string.linkSelectorDialogTitle); + + dlBuilder.setCancelable(defaultLinkHandlerScreenSelectedChoice != -1); + + dlBuilder.setSingleChoiceItems(linksArray, defaultLinkHandlerScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> { + + defaultLinkHandlerScreenSelectedChoice = i; + viewBinding.generalDeepLinkSelected.setText(linksArray[i]); + tinyDB.putInt("defaultScreenId", i); + + dialogInterfaceHomeScreen.dismiss(); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); + }); + + AlertDialog dlDialog = dlBuilder.create(); + dlDialog.show(); + }); + // link handler + } + + private void initCloseListener() { onClickListener = view -> finish(); } +} diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java new file mode 100644 index 00000000..2ba73e5e --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java @@ -0,0 +1,123 @@ +package org.mian.gitnex.activities; + +import android.graphics.Color; +import android.os.Bundle; +import android.view.View; +import android.widget.NumberPicker; +import androidx.appcompat.app.AlertDialog; +import com.pes.androidmaterialcolorpickerdialog.ColorPicker; +import org.mian.gitnex.R; +import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding; +import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.notifications.NotificationsMaster; + +/** + * Template Author M M Arif + * Author opyale + */ + +public class SettingsNotificationsActivity extends BaseActivity { + + private ActivitySettingsNotificationsBinding viewBinding; + + @Override + protected int getLayoutResourceId() { + + return R.layout.activity_settings_notifications; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + + viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); + + View.OnClickListener onClickListener = viewClose -> finish(); + + viewBinding.close.setOnClickListener(onClickListener); + + viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay))); + viewBinding.chooseColorState.setCardBackgroundColor(tinyDB.getInt("notificationsLightColor", Color.GREEN)); + + viewBinding.enableNotificationsMode.setChecked(tinyDB.getBoolean("notificationsEnabled", true)); + viewBinding.enableLightsMode.setChecked(tinyDB.getBoolean("notificationsEnableLights", true)); + viewBinding.enableVibrationMode.setChecked(tinyDB.getBoolean("notificationsEnableVibration", true)); + + viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> { + + tinyDB.putBoolean("notificationsEnabled", isChecked); + if(!isChecked) NotificationsMaster.fireWorker(ctx); + Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); + + }); + + // polling delay + viewBinding.pollingDelayFrame.setOnClickListener(v -> { + + NumberPicker numberPicker = new NumberPicker(ctx); + numberPicker.setMinValue(StaticGlobalVariables.minimumPollingDelay); + numberPicker.setMaxValue(StaticGlobalVariables.maximumPollingDelay); + numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay)); + numberPicker.setWrapSelectorWheel(true); + + AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle(getString(R.string.pollingDelayDialogHeaderText)); + builder.setMessage(getString(R.string.pollingDelayDialogDescriptionText)); + + builder.setCancelable(true); + builder.setPositiveButton(getString(R.string.okButton), (dialog, which) -> { + + tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue()); + + NotificationsMaster.fireWorker(ctx); + NotificationsMaster.hireWorker(ctx); + + viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue())); + Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); + }); + + builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss()); + builder.setView(numberPicker); + builder.create().show(); + }); + + // lights switcher + viewBinding.enableLightsMode.setOnCheckedChangeListener((buttonView, isChecked) -> { + + tinyDB.putBoolean("notificationsEnableLights", isChecked); + Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); + + }); + + // lights color chooser + viewBinding.chooseColorFrame.setOnClickListener(v -> { + + ColorPicker colorPicker = new ColorPicker(SettingsNotificationsActivity.this); + colorPicker.setColor(tinyDB.getInt("notificationsLightColor", Color.GREEN)); + colorPicker.setCallback(color -> { + + tinyDB.putInt("notificationsLightColor", color); + viewBinding.chooseColorState.setCardBackgroundColor(color); + colorPicker.dismiss(); + Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); + }); + + colorPicker.show(); + + }); + + // vibration switcher + viewBinding.enableVibrationMode.setOnCheckedChangeListener((buttonView, isChecked) -> { + + tinyDB.putBoolean("notificationsEnableVibration", isChecked); + Toasty.info(appCtx, getResources().getString(R.string.settingsSave)); + + }); + + } + +} diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsReportsActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsReportsActivity.java index d4a421fc..f296605c 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsReportsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsReportsActivity.java @@ -1,12 +1,10 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.ImageView; -import android.widget.Switch; +import com.google.android.material.switchmaterial.SwitchMaterial; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; /** @@ -15,7 +13,6 @@ import org.mian.gitnex.helpers.Toasty; public class SettingsReportsActivity extends BaseActivity { - private Context appCtx; private View.OnClickListener onClickListener; @Override @@ -28,38 +25,22 @@ public class SettingsReportsActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - TinyDB tinyDb = new TinyDB(appCtx); ImageView closeActivity = findViewById(R.id.close); initCloseListener(); closeActivity.setOnClickListener(onClickListener); - Switch crashReportsSwitch = findViewById(R.id.crashReportsSwitch); + SwitchMaterial crashReportsSwitch = findViewById(R.id.crashReportsSwitch); - if(tinyDb.getBoolean("crashReportingEnabled")) { - crashReportsSwitch.setChecked(true); - } - else { - crashReportsSwitch.setChecked(false); - } + crashReportsSwitch.setChecked(tinyDB.getBoolean("crashReportingEnabled")); // crash reports switcher crashReportsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(isChecked) { - tinyDb.putBoolean("crashReportingEnabled", true); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - else { - tinyDb.putBoolean("crashReportingEnabled", false); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - } - + tinyDB.putBoolean("crashReportingEnabled", isChecked); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); }); - } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsSecurityActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsSecurityActivity.java index 115cd117..6337d7d4 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsSecurityActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsSecurityActivity.java @@ -7,16 +7,12 @@ import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.NumberPicker; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import org.apache.commons.io.FileUtils; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; -import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; -import org.mian.gitnex.notifications.NotificationsMaster; import java.io.File; import java.io.IOException; @@ -26,21 +22,14 @@ import java.io.IOException; public class SettingsSecurityActivity extends BaseActivity { - private Context appCtx; - private Context ctx = this; - private View.OnClickListener onClickListener; - private static String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"}; + private static final String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"}; private static int cacheSizeDataSelectedChoice = 0; - private static String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"}; + private static final String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"}; private static int cacheSizeImagesSelectedChoice = 0; - private static int MINIMUM_POLLING_DELAY = 1; - private static int DEFAULT_POLLING_DELAY = 20; - private static int MAXIMUM_POLLING_DELAY = 720; - @Override protected int getLayoutResourceId() { @@ -51,10 +40,6 @@ public class SettingsSecurityActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - TinyDB tinyDb = new TinyDB(appCtx); - String currentVersion = tinyDb.getString("giteaVersion"); ImageView closeActivity = findViewById(R.id.close); @@ -64,36 +49,32 @@ public class SettingsSecurityActivity extends BaseActivity { TextView cacheSizeDataSelected = findViewById(R.id.cacheSizeDataSelected); // setter for data cache size TextView cacheSizeImagesSelected = findViewById(R.id.cacheSizeImagesSelected); // setter for images cache size TextView clearCacheSelected = findViewById(R.id.clearCacheSelected); // setter for clear cache - TextView pollingDelaySelected = findViewById(R.id.pollingDelaySelected); LinearLayout certsFrame = findViewById(R.id.certsFrame); - LinearLayout pollingDelayFrame = findViewById(R.id.pollingDelayFrame); LinearLayout cacheSizeDataFrame = findViewById(R.id.cacheSizeDataSelectionFrame); LinearLayout cacheSizeImagesFrame = findViewById(R.id.cacheSizeImagesSelectionFrame); LinearLayout clearCacheFrame = findViewById(R.id.clearCacheSelectionFrame); - if(!tinyDb.getString("cacheSizeStr").isEmpty()) { - cacheSizeDataSelected.setText(tinyDb.getString("cacheSizeStr")); + if(!tinyDB.getString("cacheSizeStr").isEmpty()) { + + cacheSizeDataSelected.setText(tinyDB.getString("cacheSizeStr")); } - if(!tinyDb.getString("cacheSizeImagesStr").isEmpty()) { - cacheSizeImagesSelected.setText(tinyDb.getString("cacheSizeImagesStr")); + if(!tinyDB.getString("cacheSizeImagesStr").isEmpty()) { + + cacheSizeImagesSelected.setText(tinyDB.getString("cacheSizeImagesStr")); } if(cacheSizeDataSelectedChoice == 0) { - cacheSizeDataSelectedChoice = tinyDb.getInt("cacheSizeId"); + + cacheSizeDataSelectedChoice = tinyDB.getInt("cacheSizeId"); } if(cacheSizeImagesSelectedChoice == 0) { - cacheSizeImagesSelectedChoice = tinyDb.getInt("cacheSizeImagesId"); - } - if(new Version(currentVersion).less("1.12.3")) { - pollingDelayFrame.setVisibility(View.GONE); + cacheSizeImagesSelectedChoice = tinyDB.getInt("cacheSizeImagesId"); } - pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDb.getInt("pollingDelayMinutes", DEFAULT_POLLING_DELAY))); - // clear cache setter File cacheDir = appCtx.getCacheDir(); clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir))); @@ -113,14 +94,11 @@ public class SettingsSecurityActivity extends BaseActivity { FileUtils.mkdir(cacheDir.getAbsolutePath()); this.recreate(); this.overridePendingTransition(0, 0); - } catch (IOException e) { Log.e("SettingsSecurity", e.toString()); - } - }); builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss()); @@ -134,28 +112,21 @@ public class SettingsSecurityActivity extends BaseActivity { AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this); tsBuilder.setTitle(getResources().getString(R.string.cacheSizeImagesDialogHeader)); - if(cacheSizeImagesSelectedChoice != -1) { - tsBuilder.setCancelable(true); - } - else { - tsBuilder.setCancelable(false); - } + tsBuilder.setCancelable(cacheSizeImagesSelectedChoice != -1); tsBuilder.setSingleChoiceItems(cacheSizeImagesList, cacheSizeImagesSelectedChoice, (dialogInterfaceTheme, i) -> { cacheSizeImagesSelectedChoice = i; cacheSizeImagesSelected.setText(cacheSizeImagesList[i]); - tinyDb.putString("cacheSizeImagesStr", cacheSizeImagesList[i]); - tinyDb.putInt("cacheSizeImagesId", i); + tinyDB.putString("cacheSizeImagesStr", cacheSizeImagesList[i]); + tinyDB.putInt("cacheSizeImagesId", i); dialogInterfaceTheme.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); AlertDialog cfDialog = tsBuilder.create(); cfDialog.show(); - }); // cache size data selection dialog @@ -164,28 +135,21 @@ public class SettingsSecurityActivity extends BaseActivity { AlertDialog.Builder tsBuilder = new AlertDialog.Builder(SettingsSecurityActivity.this); tsBuilder.setTitle(getResources().getString(R.string.cacheSizeDataDialogHeader)); - if(cacheSizeDataSelectedChoice != -1) { - tsBuilder.setCancelable(true); - } - else { - tsBuilder.setCancelable(false); - } + tsBuilder.setCancelable(cacheSizeDataSelectedChoice != -1); tsBuilder.setSingleChoiceItems(cacheSizeDataList, cacheSizeDataSelectedChoice, (dialogInterfaceTheme, i) -> { cacheSizeDataSelectedChoice = i; cacheSizeDataSelected.setText(cacheSizeDataList[i]); - tinyDb.putString("cacheSizeStr", cacheSizeDataList[i]); - tinyDb.putInt("cacheSizeId", i); + tinyDB.putString("cacheSizeStr", cacheSizeDataList[i]); + tinyDB.putInt("cacheSizeId", i); dialogInterfaceTheme.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); AlertDialog cfDialog = tsBuilder.create(); cfDialog.show(); - }); // certs deletion @@ -199,53 +163,18 @@ public class SettingsSecurityActivity extends BaseActivity { appCtx.getSharedPreferences(MemorizingTrustManager.KEYSTORE_NAME, Context.MODE_PRIVATE).edit().remove(MemorizingTrustManager.KEYSTORE_KEY).apply(); - tinyDb.putBoolean("loggedInMode", false); - tinyDb.remove("basicAuthPassword"); - tinyDb.putBoolean("basicAuthFlag", false); + tinyDB.putBoolean("loggedInMode", false); + tinyDB.remove("basicAuthPassword"); + tinyDB.putBoolean("basicAuthFlag", false); Intent loginActivityIntent = new Intent().setClass(appCtx, LoginActivity.class); loginActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); appCtx.startActivity(loginActivityIntent); - }); builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss()); builder.create().show(); - }); - - // polling delay - pollingDelayFrame.setOnClickListener(v -> { - - NumberPicker numberPicker = new NumberPicker(ctx); - numberPicker.setMinValue(MINIMUM_POLLING_DELAY); - numberPicker.setMaxValue(MAXIMUM_POLLING_DELAY); - numberPicker.setValue(tinyDb.getInt("pollingDelayMinutes", DEFAULT_POLLING_DELAY)); - numberPicker.setWrapSelectorWheel(true); - - AlertDialog.Builder builder = new AlertDialog.Builder(ctx); - builder.setTitle(getString(R.string.pollingDelayDialogHeaderText)); - builder.setMessage(getString(R.string.pollingDelayDialogDescriptionText)); - - builder.setCancelable(true); - builder.setPositiveButton(getString(R.string.okButton), (dialog, which) -> { - - tinyDb.putInt("pollingDelayMinutes", numberPicker.getValue()); - - NotificationsMaster.fireWorker(ctx); - NotificationsMaster.hireWorker(ctx); - - pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue())); - Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - - }); - - builder.setNeutralButton(R.string.cancelButton, null); - builder.setView(numberPicker); - builder.create().show(); - - }); - } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsTranslationActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsTranslationActivity.java index 392c618c..3f8769e0 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsTranslationActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsTranslationActivity.java @@ -1,6 +1,5 @@ package org.mian.gitnex.activities; -import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -10,7 +9,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; /** @@ -19,7 +17,6 @@ import org.mian.gitnex.helpers.Toasty; public class SettingsTranslationActivity extends BaseActivity { - private Context appCtx; private View.OnClickListener onClickListener; private static String[] langList = {"English", "Arabic", "Chinese", "Czech", "Finnish", "French", "German", "Italian", "Latvian", "Persian", @@ -36,9 +33,6 @@ public class SettingsTranslationActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appCtx = getApplicationContext(); - - TinyDB tinyDb = new TinyDB(appCtx); ImageView closeActivity = findViewById(R.id.close); @@ -60,12 +54,14 @@ public class SettingsTranslationActivity extends BaseActivity { }); - if(!tinyDb.getString("localeStr").isEmpty()) { - tvLanguageSelected.setText(tinyDb.getString("localeStr")); + if(!tinyDB.getString("localeStr").isEmpty()) { + + tvLanguageSelected.setText(tinyDB.getString("localeStr")); } if(langSelectedChoice == 0) { - langSelectedChoice = tinyDb.getInt("langId"); + + langSelectedChoice = tinyDB.getInt("langId"); } // language dialog @@ -74,89 +70,98 @@ public class SettingsTranslationActivity extends BaseActivity { AlertDialog.Builder lBuilder = new AlertDialog.Builder(SettingsTranslationActivity.this); lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle); - if(langSelectedChoice != -1) { - lBuilder.setCancelable(true); - } - else { - lBuilder.setCancelable(false); - } + lBuilder.setCancelable(langSelectedChoice != -1); lBuilder.setSingleChoiceItems(langList, langSelectedChoice, (dialogInterface, i) -> { langSelectedChoice = i; tvLanguageSelected.setText(langList[i]); - tinyDb.putString("localeStr", langList[i]); - tinyDb.putInt("langId", i); + tinyDB.putString("localeStr", langList[i]); + tinyDB.putInt("langId", i); switch(langList[i]) { case "Arabic": - tinyDb.putString("locale", "ar"); + + tinyDB.putString("locale", "ar"); break; case "Chinese": - tinyDb.putString("locale", "zh"); + + tinyDB.putString("locale", "zh"); break; case "Czech": - tinyDb.putString("locale", "cs"); + + tinyDB.putString("locale", "cs"); break; case "Finnish": - tinyDb.putString("locale", "fi"); + + tinyDB.putString("locale", "fi"); break; case "French": - tinyDb.putString("locale", "fr"); + + tinyDB.putString("locale", "fr"); break; case "German": - tinyDb.putString("locale", "de"); + + tinyDB.putString("locale", "de"); break; case "Italian": - tinyDb.putString("locale", "it"); + + tinyDB.putString("locale", "it"); break; case "Latvian": - tinyDb.putString("locale", "lv"); + + tinyDB.putString("locale", "lv"); break; case "Persian": - tinyDb.putString("locale", "fa"); + + tinyDB.putString("locale", "fa"); break; case "Polish": - tinyDb.putString("locale", "pl"); + + tinyDB.putString("locale", "pl"); break; case "Portuguese/Brazilian": - tinyDb.putString("locale", "pt"); + + tinyDB.putString("locale", "pt"); break; case "Russian": - tinyDb.putString("locale", "ru"); + + tinyDB.putString("locale", "ru"); break; case "Serbian": - tinyDb.putString("locale", "sr"); + + tinyDB.putString("locale", "sr"); break; case "Spanish": - tinyDb.putString("locale", "es"); + + tinyDB.putString("locale", "es"); break; case "Turkish": - tinyDb.putString("locale", "tr"); + + tinyDB.putString("locale", "tr"); break; case "Ukrainian": - tinyDb.putString("locale", "uk"); + + tinyDB.putString("locale", "uk"); break; default: - tinyDb.putString("locale", "en"); + + tinyDB.putString("locale", "en"); break; } - tinyDb.putBoolean("refreshParent", true); + tinyDB.putBoolean("refreshParent", true); this.recreate(); this.overridePendingTransition(0, 0); dialogInterface.dismiss(); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); lBuilder.setNeutralButton(getString(R.string.cancelButton), null); AlertDialog lDialog = lBuilder.create(); lDialog.show(); - }); - } private void initCloseListener() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java index d80fa661..fcc823af 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/AssigneesListAdapter.java @@ -50,12 +50,13 @@ public class AssigneesListAdapter extends RecyclerView.Adapter(new LinkedHashSet<>(currentAssignees)); + for(int i = 0; i < currentAssignees.size(); i++) { if(currentAssignees.contains(currentItem.getLogin())) { @@ -98,6 +102,7 @@ public class AssigneesListAdapter extends RecyclerView.Adapter { @@ -119,6 +124,7 @@ public class AssigneesListAdapter extends RecyclerView.Adapter { private List draftsList; - private FragmentManager fragmentManager; - private Context mCtx; + private final FragmentManager fragmentManager; + private final Context mCtx; class DraftsViewHolder extends RecyclerView.ViewHolder { - private TextView draftText; - private TextView repoInfo; - private TextView repoId; - private TextView draftId; - private TextView issueNumber; - private TextView issueType; - private TextView repoOwner; - private TextView repoName; - private TextView commentId; - private ImageView editCommentStatus; + private DraftWithRepository draftWithRepository; + + private final TextView draftText; + private final TextView repoInfo; + private final ImageView editCommentStatus; private DraftsViewHolder(View itemView) { @@ -50,19 +48,12 @@ public class DraftsAdapter extends RecyclerView.Adapter { - int getDraftId = Integer.parseInt(draftId.getText().toString()); + int getDraftId = draftWithRepository.getDraftId(); deleteDraft(getAdapterPosition()); DraftsApi draftsApi = new DraftsApi(mCtx); draftsApi.deleteSingleDraft(getDraftId); @@ -73,23 +64,26 @@ public class DraftsAdapter extends RecyclerView.Adapter mCtx.startActivity(new Intent(mCtx, IssueDetailActivity.class))); + bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet"); }); @@ -125,18 +119,13 @@ public class DraftsAdapter extends RecyclerView.Adapter" + mCtx.getResources().getString(R.string.hash) + currentItem.getIssueId() + ""; Spanned headTitle = Html.fromHtml(issueNumber + " " + currentItem.getRepositoryOwner() + " / " + currentItem.getRepositoryName()); + holder.repoInfo.setText(headTitle); + holder.draftWithRepository = currentItem; + + new Markdown(mCtx, currentItem.getDraftText(), holder.draftText); if(!currentItem.getCommentId().equalsIgnoreCase("new")) { holder.editCommentStatus.setVisibility(View.VISIBLE); @@ -144,7 +133,6 @@ public class DraftsAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/FilesDiffAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/FilesDiffAdapter.java index f790f3c2..86bec71c 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/FilesDiffAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/FilesDiffAdapter.java @@ -15,8 +15,9 @@ import android.widget.TextView; import androidx.fragment.app.FragmentManager; import org.mian.gitnex.R; import org.mian.gitnex.fragments.BottomSheetReplyFragment; -import org.mian.gitnex.helpers.DiffTextView; +import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.models.FileDiffView; +import org.mian.gitnex.views.DiffTextView; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; @@ -36,9 +37,9 @@ public class FilesDiffAdapter extends BaseAdapter { private static int COLOR_SELECTED; private static int COLOR_FONT; - private Context context; - private FragmentManager fragmentManager; - private List fileDiffViews; + private final Context context; + private final FragmentManager fragmentManager; + private final List fileDiffViews; public FilesDiffAdapter(Context context, FragmentManager fragmentManager, List fileDiffViews) { @@ -48,11 +49,11 @@ public class FilesDiffAdapter extends BaseAdapter { selectedViews = new ConcurrentSkipListMap<>(); - COLOR_ADDED = getColorFromAttribute(R.attr.diffAddedColor); - COLOR_REMOVED = getColorFromAttribute(R.attr.diffRemovedColor); - COLOR_NORMAL = getColorFromAttribute(R.attr.primaryBackgroundColor); - COLOR_SELECTED = getColorFromAttribute(R.attr.diffSelectedColor); - COLOR_FONT = getColorFromAttribute(R.attr.inputTextColor); + COLOR_ADDED = AppUtil.getColorFromAttribute(context, R.attr.diffAddedColor); + COLOR_REMOVED = AppUtil.getColorFromAttribute(context, R.attr.diffRemovedColor); + COLOR_NORMAL = AppUtil.getColorFromAttribute(context, R.attr.primaryBackgroundColor); + COLOR_SELECTED = AppUtil.getColorFromAttribute(context, R.attr.diffSelectedColor); + COLOR_FONT = AppUtil.getColorFromAttribute(context, R.attr.inputTextColor); } @@ -185,7 +186,6 @@ public class FilesDiffAdapter extends BaseAdapter { }); - diffTextView.setOnLongClickListener(v -> { if(((DiffTextView) v).getCurrentBackgroundColor() == COLOR_SELECTED) { @@ -257,13 +257,4 @@ public class FilesDiffAdapter extends BaseAdapter { } - private int getColorFromAttribute(int resid) { - - TypedValue typedValue = new TypedValue(); - context.getTheme().resolveAttribute(resid, typedValue, true); - - return typedValue.data; - - } - } diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java index c2443b26..13df14d1 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java @@ -5,14 +5,12 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Bundle; -import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; @@ -25,33 +23,18 @@ import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.fragments.BottomSheetReplyFragment; import org.mian.gitnex.helpers.AlertDialogs; -import org.mian.gitnex.helpers.ClickListener; +import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Markdown; 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.models.IssueComments; -import java.util.Collection; -import java.util.Collections; +import org.mian.gitnex.views.ReactionList; +import org.mian.gitnex.views.ReactionSpinner; import java.util.List; import java.util.Locale; import java.util.Objects; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.core.CorePlugin; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.ext.tables.TablePlugin; -import io.noties.markwon.ext.tasklist.TaskListPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.image.DefaultMediaDecoder; -import io.noties.markwon.image.ImageItem; -import io.noties.markwon.image.ImagesPlugin; -import io.noties.markwon.image.SchemeHandler; -import io.noties.markwon.image.gif.GifMediaDecoder; -import io.noties.markwon.image.svg.SvgMediaDecoder; -import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Call; import retrofit2.Callback; @@ -61,94 +44,115 @@ import retrofit2.Callback; public class IssueCommentsAdapter extends RecyclerView.Adapter { - private List issuesComments; - private FragmentManager fragmentManager; - private Context mCtx; + private final Context ctx; + private final TinyDB tinyDB; + private final Bundle bundle; + private final List issuesComments; + private final FragmentManager fragmentManager; + private final BottomSheetReplyFragment.OnInteractedListener onInteractedListener; - public IssueCommentsAdapter(Context mCtx, FragmentManager fragmentManager, List issuesCommentsMain) { + public IssueCommentsAdapter(Context ctx, Bundle bundle, List issuesCommentsMain, FragmentManager fragmentManager, BottomSheetReplyFragment.OnInteractedListener onInteractedListener) { - this.mCtx = mCtx; - this.fragmentManager = fragmentManager; + this.ctx = ctx; + this.bundle = bundle; this.issuesComments = issuesCommentsMain; + this.fragmentManager = fragmentManager; + this.onInteractedListener = onInteractedListener; + + tinyDB = TinyDB.getInstance(ctx); } class IssueCommentViewHolder extends RecyclerView.ViewHolder { - private TextView issueNumber; - private TextView commendId; - private ImageView issueCommenterAvatar; - private TextView issueComment; - private TextView issueCommentDate; - private TextView commendBodyRaw; - private TextView commentModified; - private TextView commenterUsername; - private TextView htmlUrl; + private IssueComments issueComment; - private IssueCommentViewHolder(View itemView) { + private final ImageView avatar; + private final TextView author; + private final TextView information; + private final TextView comment; + private final LinearLayout commentReactionBadges; - super(itemView); + private IssueCommentViewHolder(View view) { - issueNumber = itemView.findViewById(R.id.issueNumber); - commendId = itemView.findViewById(R.id.commendId); - issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar); - issueComment = itemView.findViewById(R.id.issueComment); - issueCommentDate = itemView.findViewById(R.id.issueCommentDate); - ImageView commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu); - commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw); - commentModified = itemView.findViewById(R.id.commentModified); - commenterUsername = itemView.findViewById(R.id.commenterUsername); - htmlUrl = itemView.findViewById(R.id.htmlUrl); + super(view); - commentsOptionsMenu.setOnClickListener(v -> { + avatar = view.findViewById(R.id.avatar); + author = view.findViewById(R.id.author); + information = view.findViewById(R.id.information); + ImageView menu = view.findViewById(R.id.menu); + comment = view.findViewById(R.id.comment); + commentReactionBadges = view.findViewById(R.id.commentReactionBadges); + + menu.setOnClickListener(v -> { final Context ctx = v.getContext(); - final TinyDB tinyDb = new TinyDB(ctx); - final String loginUid = tinyDb.getString("loginUid"); + final String loginUid = tinyDB.getString("loginUid"); - @SuppressLint("InflateParams") View view = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null); + @SuppressLint("InflateParams") View vw = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null); - TextView commentMenuEdit = view.findViewById(R.id.commentMenuEdit); - TextView commentShare = view.findViewById(R.id.issueCommentShare); - TextView commentMenuQuote = view.findViewById(R.id.commentMenuQuote); - TextView commentMenuCopy = view.findViewById(R.id.commentMenuCopy); - TextView commentMenuDelete = view.findViewById(R.id.commentMenuDelete); - TextView issueCommentCopyUrl = view.findViewById(R.id.issueCommentCopyUrl); + TextView commentMenuEdit = vw.findViewById(R.id.commentMenuEdit); + TextView commentShare = vw.findViewById(R.id.issueCommentShare); + TextView commentMenuQuote = vw.findViewById(R.id.commentMenuQuote); + TextView commentMenuCopy = vw.findViewById(R.id.commentMenuCopy); + TextView commentMenuDelete = vw.findViewById(R.id.commentMenuDelete); + TextView issueCommentCopyUrl = vw.findViewById(R.id.issueCommentCopyUrl); - if(!loginUid.contentEquals(commenterUsername.getText())) { + if(!loginUid.contentEquals(issueComment.getUser().getUsername())) { commentMenuEdit.setVisibility(View.GONE); commentMenuDelete.setVisibility(View.GONE); } - if(issueComment.getText().toString().isEmpty()) { + if(issueComment.getBody().isEmpty()) { commentMenuCopy.setVisibility(View.GONE); } BottomSheetDialog dialog = new BottomSheetDialog(ctx); - dialog.setContentView(view); + dialog.setContentView(vw); dialog.show(); - commentMenuEdit.setOnClickListener(ediComment -> { + LinearLayout linearLayout = vw.findViewById(R.id.commentReactionButtons); - Bundle bundle = new Bundle(); - bundle.putString("commentId", commendId.getText().toString()); - bundle.putString("commentAction", "edit"); - bundle.putString("commentBody", commendBodyRaw.getText().toString()); + Bundle bundle1 = new Bundle(); + bundle1.putAll(bundle); + bundle1.putInt("commentId", issueComment.getId()); - BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet"); + ReactionSpinner reactionSpinner = new ReactionSpinner(ctx, bundle1); + reactionSpinner.setOnInteractedListener(() -> { + + tinyDB.putBoolean("commentEdited", true); + + onInteractedListener.onInteracted(); dialog.dismiss(); }); - commentShare.setOnClickListener(ediComment -> { + linearLayout.addView(reactionSpinner); + + commentMenuEdit.setOnClickListener(v1 -> { + + Bundle bundle = new Bundle(); + bundle.putInt("commentId", issueComment.getId()); + bundle.putString("commentAction", "edit"); + bundle.putString("commentBody", issueComment.getBody()); + + BottomSheetReplyFragment bottomSheetReplyFragment = BottomSheetReplyFragment.newInstance(bundle); + bottomSheetReplyFragment.setOnInteractedListener(onInteractedListener); + bottomSheetReplyFragment.show(fragmentManager, "replyBottomSheet"); + + dialog.dismiss(); + + }); + + commentShare.setOnClickListener(v1 -> { // get comment Url - CharSequence commentUrl = htmlUrl.getText(); + CharSequence commentUrl = issueComment.getHtml_url(); // share issue comment Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); - String intentHeader = tinyDb.getString("issueNumber") + ctx.getResources().getString(R.string.hash) + "issuecomment-" + commendId.getText() + " " + tinyDb.getString("issueTitle"); + String intentHeader = tinyDB.getString("issueNumber") + ctx.getResources().getString(R.string.hash) + "issuecomment-" + issueComment.getId() + " " + tinyDB.getString("issueTitle"); sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, intentHeader); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, commentUrl); ctx.startActivity(Intent.createChooser(sharingIntent, intentHeader)); @@ -157,10 +161,10 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter { + issueCommentCopyUrl.setOnClickListener(v1 -> { // comment Url - CharSequence commentUrl = htmlUrl.getText(); + CharSequence commentUrl = issueComment.getHtml_url(); ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); assert clipboard != null; @@ -176,14 +180,14 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter { StringBuilder stringBuilder = new StringBuilder(); - String commenterName = commenterUsername.getText().toString(); + String commenterName = issueComment.getUser().getUsername(); - if(!commenterName.equals(tinyDb.getString("userLogin"))) { + if(!commenterName.equals(tinyDB.getString("userLogin"))) { stringBuilder.append("@").append(commenterName).append("\n\n"); } - String[] lines = commendBodyRaw.getText().toString().split("\\R"); + String[] lines = issueComment.getBody().split("\\R"); for(String line : lines) { @@ -201,12 +205,12 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter { + commentMenuCopy.setOnClickListener(v1 -> { ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE); assert clipboard != null; - ClipData clip = ClipData.newPlainText("Comment on issue #" + issueNumber.getText().toString(), issueComment.getText().toString()); + ClipData clip = ClipData.newPlainText("Comment on issue #" + tinyDB.getString("issueNumber"), issueComment.getBody()); clipboard.setPrimaryClip(clip); dialog.dismiss(); @@ -214,9 +218,9 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter { + commentMenuDelete.setOnClickListener(v1 -> { - deleteIssueComment(ctx, Integer.parseInt(commendId.getText().toString()), getAdapterPosition()); + deleteIssueComment(ctx, issueComment.getId(), getAdapterPosition()); dialog.dismiss(); }); @@ -237,22 +241,19 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter call; - - call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + Call call = RetrofitClient + .getApiInterface(ctx) .deleteComment(instanceToken, repoOwner, repoName, commentId); call.enqueue(new Callback() { @@ -260,47 +261,40 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter call, @NonNull retrofit2.Response response) { - if(response.code() == 204) { + switch(response.code()) { - updateAdapter(position); - Toasty.success(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess)); + case 204: + updateAdapter(position); + Toasty.success(ctx, ctx.getResources().getString(R.string.deleteCommentSuccess)); + break; - } - else if(response.code() == 401) { - - AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), + case 401: + AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle), ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + break; + + case 403: + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + break; + + case 404: + Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); + break; + + default: + Toasty.error(ctx, ctx.getString(R.string.genericError)); } - 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, ctx.getString(R.string.genericError)); - - } - } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { Toasty.error(ctx, ctx.getResources().getString(R.string.genericServerResponseError)); - } - }); - } @NonNull @@ -311,109 +305,70 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter supportedSchemes() { - - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); + informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "pretty", ctx)); + holder.information.setOnClickListener(v -> TimeHelper.customDateFormatForToastDateFormat(issueComment.getCreated_at())); } - })).usePlugin(new AbstractMarkwonPlugin() { + else if(timeFormat.equals("normal")) { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - - builder.codeTextColor(tinyDb.getInt("codeBlockColor")).codeBackgroundColor(tinyDb.getInt("codeBlockBackground")).linkColor(mCtx.getResources().getColor(R.color.lightBlue)); + informationBuilder = new StringBuilder(TimeHelper.formatTime(issueComment.getCreated_at(), Locale.getDefault(), "normal", ctx)); } - }).usePlugin(TablePlugin.create(mCtx)).usePlugin(TaskListPlugin.create(mCtx)).usePlugin(HtmlPlugin.create()).usePlugin(StrikethroughPlugin.create()).usePlugin(LinkifyPlugin.create()).build(); + if(!issueComment.getCreated_at().equals(issueComment.getUpdated_at())) { - Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments)); - markwon.setParsedMarkdown(holder.issueComment, UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments)); - - String edited; - - if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) { - - edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText); - holder.commentModified.setVisibility(View.VISIBLE); - holder.commentModified.setText(edited); - holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx)); - - } - else { - - holder.commentModified.setVisibility(View.INVISIBLE); + if(informationBuilder != null) { + informationBuilder.append(ctx.getString(R.string.colorfulBulletSpan)).append(ctx.getString(R.string.modifiedText)); + } + } } - holder.issueCommentDate.setText(TimeHelper.formatTime(currentItem.getCreated_at(), new Locale(locale), timeFormat, mCtx)); + holder.information.setText(informationBuilder); + + Bundle bundle1 = new Bundle(); + bundle1.putAll(bundle); + bundle1.putInt("commentId", issueComment.getId()); + + ReactionList reactionList = new ReactionList(ctx, bundle1); + + holder.commentReactionBadges.addView(reactionList); + reactionList.setOnReactionAddedListener(() -> { + + if(holder.commentReactionBadges.getVisibility() != View.VISIBLE) { + holder.commentReactionBadges.post(() -> holder.commentReactionBadges.setVisibility(View.VISIBLE)); + } + }); - if(timeFormat.equals("pretty")) { - holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx)); - } } @Override public int getItemCount() { return issuesComments.size(); - } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java index b1f56f5f..d51d0868 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java @@ -123,7 +123,7 @@ public class IssuesAdapter extends RecyclerView.Adapter Intent intent = new Intent(context, IssueDetailActivity.class); intent.putExtra("issueNumber", issueNumber.getText()); - TinyDB tinyDb = new TinyDB(context); + TinyDB tinyDb = TinyDB.getInstance(context); tinyDb.putString("issueNumber", issueNumber.getText().toString()); tinyDb.putString("issueType", "Issue"); context.startActivity(intent); @@ -136,7 +136,7 @@ public class IssuesAdapter extends RecyclerView.Adapter Intent intent = new Intent(context, IssueDetailActivity.class); intent.putExtra("issueNumber", issueNumber.getText()); - TinyDB tinyDb = new TinyDB(context); + TinyDB tinyDb = TinyDB.getInstance(context); tinyDb.putString("issueNumber", issueNumber.getText().toString()); tinyDb.putString("issueType", "Issue"); context.startActivity(intent); @@ -148,7 +148,7 @@ public class IssuesAdapter extends RecyclerView.Adapter @SuppressLint("SetTextI18n") void bindData(Issues issuesModel) { - final TinyDB tinyDb = new TinyDB(context); + final TinyDB tinyDb = TinyDB.getInstance(context); final String locale = tinyDb.getString("locale"); final String timeFormat = tinyDb.getString("dateFormat"); diff --git a/app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java index 71803012..73d8cab3 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java @@ -32,6 +32,8 @@ public class LabelsAdapter extends RecyclerView.Adapter labelsList; final private Context mCtx; private ArrayList labelsArray = new ArrayList<>(); + private static String type; + private static String orgName; static class LabelsViewHolder extends RecyclerView.ViewHolder { @@ -77,6 +79,8 @@ public class LabelsAdapter extends RecyclerView.Adapter labelsMain) { + public LabelsAdapter(Context mCtx, List labelsMain, String type, String orgName) { + this.mCtx = mCtx; this.labelsList = labelsMain; + LabelsAdapter.type = type; + LabelsAdapter.orgName = orgName; } @NonNull 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 be152b12..4a01cb16 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/LabelsListAdapter.java @@ -48,12 +48,13 @@ public class LabelsListAdapter extends RecyclerView.Adapter(new LinkedHashSet<>(currentLabelsIds)); + for(int i = 0; i < currentLabelsIds.size(); i++) { if(currentLabelsIds.contains(currentItem.getId())) { @@ -93,6 +95,7 @@ public class LabelsListAdapter extends RecyclerView.Adapter { @@ -117,6 +120,7 @@ public class LabelsListAdapter extends RecyclerView.Adapter { - plugin.addSchemeHandler(new SchemeHandler() { - - @NonNull - @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = context.getResources().getIdentifier( - raw.substring("drawable://".length()), - "drawable", - context.getPackageName()); - - final Drawable drawable = context.getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); - } - - @NonNull - @Override - public Collection supportedSchemes() { - return Collections.singleton("drawable"); - } - }); - - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - - })) - - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder - .codeTextColor(tinyDb.getInt("codeBlockColor")) - .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(context.getResources().getColor(R.color.lightBlue)); - } - }) - .usePlugin(TablePlugin.create(context)) - .usePlugin(TaskListPlugin.create(context)) - .usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create()) - .build(); - - Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle()); - markwon.setParsedMarkdown(msTitle, msTitle_); + new Markdown(context, dataModel.getTitle(), msTitle); if(!dataModel.getDescription().equals("")) { - CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription())); - msDescription.setText(bodyWithMD); - + new Markdown(context, EmojiParser.parseToUnicode(dataModel.getDescription()), msDescription); } else { diff --git a/app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java index f1257347..c069ba36 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MyReposListAdapter.java @@ -92,7 +92,7 @@ public class MyReposListAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/NotificationsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/NotificationsAdapter.java index 5c7a3473..74398aeb 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/NotificationsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/NotificationsAdapter.java @@ -31,7 +31,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter notificationThreads, OnMoreClickedListener onMoreClickedListener, OnNotificationClickedListener onNotificationClickedListener) { - this.tinyDb = new TinyDB(context); + this.tinyDb = TinyDB.getInstance(context); this.context = context; this.notificationThreads = notificationThreads; this.onMoreClickedListener = onMoreClickedListener; diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java index d5aca9dd..929ae2bb 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java @@ -45,27 +45,23 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter { - Context context = v.getContext(); - Intent intent = new Intent(context, OrganizationDetailActivity.class); - intent.putExtra("orgName", mTextView1.getText().toString()); + Context context = v.getContext(); + Intent intent = new Intent(context, OrganizationDetailActivity.class); + intent.putExtra("orgName", mTextView1.getText().toString()); - TinyDB tinyDb = new TinyDB(context); - tinyDb.putString("orgName", mTextView1.getText().toString()); - tinyDb.putString("organizationId", organizationId.getText().toString()); - tinyDb.putBoolean("organizationAction", true); - context.startActivity(intent); - - } + TinyDB tinyDb = TinyDB.getInstance(context); + tinyDb.putString("orgName", mTextView1.getText().toString()); + tinyDb.putString("organizationId", organizationId.getText().toString()); + tinyDb.putBoolean("organizationAction", true); + context.startActivity(intent); }); - } } public OrganizationsListAdapter(Context mCtx, List orgsListMain) { + this.mCtx = mCtx; this.orgList = orgsListMain; orgListFull = new ArrayList<>(orgList); @@ -74,6 +70,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter filteredList = new ArrayList<>(); if (constraint == null || constraint.length() == 0) { + filteredList.addAll(orgListFull); - } else { + } + else { + String filterPattern = constraint.toString().toLowerCase().trim(); for (UserOrganizations item : orgListFull) { @@ -130,6 +133,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter { - plugin.addSchemeHandler(new SchemeHandler() { - @NonNull - @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = mCtx.getResources().getIdentifier( - raw.substring("drawable://".length()), - "drawable", - mCtx.getPackageName()); - - final Drawable drawable = mCtx.getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); - } - - @NonNull - @Override - public Collection supportedSchemes() { - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder - .codeTextColor(tinyDb.getInt("codeBlockColor")) - .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(mCtx.getResources().getColor(R.color.lightBlue)); - } - }) - .usePlugin(TablePlugin.create(mCtx)) - .usePlugin(TaskListPlugin.create(mCtx)) - .usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create()) - .build(); - - Spanned bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody())); - if(!currentItem.getBody().equals("")) { - markwon.setParsedMarkdown(holder.releaseBodyContent, bodyWithMD); + new Markdown(mCtx, currentItem.getBody(), holder.releaseBodyContent); } else { holder.releaseBodyContent.setText(R.string.noReleaseBodyContent); diff --git a/app/src/main/java/org/mian/gitnex/adapters/RepoForksAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/RepoForksAdapter.java index cd32fdb3..851d90e6 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/RepoForksAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/RepoForksAdapter.java @@ -211,7 +211,7 @@ public class RepoForksAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/RepoStargazersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/RepoStargazersAdapter.java index 1dc95f2c..e05fe633 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/RepoStargazersAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/RepoStargazersAdapter.java @@ -81,7 +81,7 @@ public class RepoStargazersAdapter extends BaseAdapter { UserInfo currentItem = stargazersList.get(position); PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); - final TinyDB tinyDb = new TinyDB(mCtx); + final TinyDB tinyDb = TinyDB.getInstance(mCtx); Typeface myTypeface; switch(tinyDb.getInt("customFontId", -1)) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java index 8b59f1af..3a570764 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java @@ -81,7 +81,7 @@ public class RepoWatchersAdapter extends BaseAdapter { UserInfo currentItem = watchersList.get(position); PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); - final TinyDB tinyDb = new TinyDB(mCtx); + final TinyDB tinyDb = TinyDB.getInstance(mCtx); Typeface myTypeface; switch(tinyDb.getInt("customFontId", -1)) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java index 5a56ccd6..b522ae90 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java @@ -23,9 +23,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog; import org.mian.gitnex.R; import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.RepoDetailActivity; +import org.mian.gitnex.activities.RepoForksActivity; import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoWatchersActivity; -import org.mian.gitnex.activities.RepoForksActivity; import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.database.api.RepositoriesApi; @@ -94,7 +94,7 @@ public class ReposListAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java index a7786d10..7736856f 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/RepositoriesByOrgAdapter.java @@ -23,9 +23,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog; import org.mian.gitnex.R; import org.mian.gitnex.activities.OpenRepoInBrowserActivity; import org.mian.gitnex.activities.RepoDetailActivity; +import org.mian.gitnex.activities.RepoForksActivity; import org.mian.gitnex.activities.RepoStargazersActivity; import org.mian.gitnex.activities.RepoWatchersActivity; -import org.mian.gitnex.activities.RepoForksActivity; import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.database.api.RepositoriesApi; @@ -91,7 +91,7 @@ public class RepositoriesByOrgAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java index 379029e4..bca1123f 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java @@ -40,7 +40,7 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter call; - call = RetrofitClient.getInstance(instanceUrl, context).getApiInterface().checkRepoWatchStatus(token, repoOwner, repoName); + call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java index 0cafefb4..d71fb741 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java @@ -82,7 +82,7 @@ public class TeamMembersByOrgAdapter extends BaseAdapter { UserInfo currentItem = teamMembersList.get(position); PicassoService.getInstance(mCtx).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar); - final TinyDB tinyDb = new TinyDB(mCtx); + final TinyDB tinyDb = TinyDB.getInstance(mCtx); Typeface myTypeface; switch(tinyDb.getInt("customFontId", -1)) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java index aa7766ed..99b18a4d 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsAdapter.java @@ -125,7 +125,7 @@ public class UserAccountsAdapter extends RecyclerView.Adapter { super(mCtx, resource, userAccounts); - tinyDB = new TinyDB(mCtx); + tinyDB = TinyDB.getInstance(mCtx); this.userAccounts = userAccounts; this.mCtx = mCtx; diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserAccountsNavAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsNavAdapter.java index 5241889d..f09f6fa7 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/UserAccountsNavAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/UserAccountsNavAdapter.java @@ -96,7 +96,7 @@ public class UserAccountsNavAdapter extends RecyclerView.Adapter allAccountsList) { - TinyDB tinyDB = new TinyDB(mCtx); + TinyDB tinyDB = TinyDB.getInstance(mCtx); Dialog dialog = new Dialog(mCtx, R.style.ThemeOverlay_MaterialComponents_Dialog_Alert); dialog.setContentView(R.layout.custom_user_accounts_dialog); diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java index ea2ebe36..b8b7317f 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java @@ -146,19 +146,16 @@ public class UserSearchAdapter extends RecyclerView.Adapter 0) { - TinyDB tinyDb = new TinyDB(mCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(mCtx); 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"); Call call = RetrofitClient - .getInstance(instanceUrl, mCtx) - .getApiInterface() - .checkRepoCollaborator(Authorization.returnAuthentication(mCtx, loginUid, instanceToken), repoOwner, repoName, currentItem.getUsername()); + .getApiInterface(mCtx) + .checkRepoCollaborator(Authorization.get(mCtx), repoOwner, repoName, currentItem.getUsername()); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java index 71c48437..74129604 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java @@ -116,8 +116,7 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter 0) { - TinyDB tinyDb = new TinyDB(mCtx); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(mCtx); final String loginUid = tinyDb.getString("loginUid"); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); @@ -125,9 +124,8 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter call = RetrofitClient - .getInstance(instanceUrl, mCtx) - .getApiInterface() - .checkTeamMember(Authorization.returnAuthentication(mCtx, loginUid, instanceToken), teamId, currentItem.getLogin()); + .getApiInterface(mCtx) + .checkTeamMember(Authorization.get(mCtx), teamId, currentItem.getLogin()); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/clients/AppApiService.java b/app/src/main/java/org/mian/gitnex/clients/AppApiService.java deleted file mode 100644 index 9e6a6de9..00000000 --- a/app/src/main/java/org/mian/gitnex/clients/AppApiService.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.mian.gitnex.clients; - -import android.content.Context; -import android.util.Log; -import org.mian.gitnex.helpers.AppUtil; -import org.mian.gitnex.helpers.FilesData; -import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; -import java.io.File; -import java.security.SecureRandom; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.X509TrustManager; -import okhttp3.Cache; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.logging.HttpLoggingInterceptor; -import retrofit2.Retrofit; -import retrofit2.converter.gson.GsonConverterFactory; - -/** - * Author M M Arif - */ - -public class AppApiService { - - public static S createService(Class serviceClass, String instanceURL, Context ctx) { - - TinyDB tinyDb = new TinyDB(ctx); - final boolean connToInternet = AppUtil.hasNetworkConnection(ctx); - File httpCacheDirectory = new File(ctx.getCacheDir(), "responses"); - int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024; - Cache cache = new Cache(httpCacheDirectory, cacheSize); - - HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); - logging.setLevel(HttpLoggingInterceptor.Level.BODY); - - try { - - SSLContext sslContext = SSLContext.getInstance("TLS"); - - MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx); - sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom()); - - OkHttpClient okHttpClient = new OkHttpClient.Builder() - .cache(cache) - //.addInterceptor(logging) - .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) - .hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())) - .addInterceptor(chain -> { - - Request request = chain.request(); - if(connToInternet) { - request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); - } - else { - request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); - } - return chain.proceed(request); - - }).build(); - - Retrofit.Builder builder = new Retrofit.Builder() - .baseUrl(instanceURL) - .client(okHttpClient) - .addConverterFactory(GsonConverterFactory.create()); - - Retrofit retrofit = builder.build(); - return retrofit.create(serviceClass); - - } - catch(Exception e) { - Log.e("onFailure", e.toString()); - } - - return null; - } - -} diff --git a/app/src/main/java/org/mian/gitnex/clients/PicassoService.java b/app/src/main/java/org/mian/gitnex/clients/PicassoService.java index fc76091e..aa1cd7f8 100644 --- a/app/src/main/java/org/mian/gitnex/clients/PicassoService.java +++ b/app/src/main/java/org/mian/gitnex/clients/PicassoService.java @@ -20,7 +20,7 @@ import okhttp3.OkHttpClient; public class PicassoService { private static PicassoService picassoService; - private static File cachePath; + private final File cachePath; private Picasso picasso; private PicassoService(Context context) { @@ -54,7 +54,6 @@ public class PicassoService { Log.e("PicassoService", e.toString()); } - } public Picasso get() { diff --git a/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java b/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java index 8161eb8a..9304d051 100644 --- a/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java +++ b/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java @@ -10,6 +10,8 @@ import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.interfaces.WebInterface; import java.io.File; import java.security.SecureRandom; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -27,15 +29,15 @@ import retrofit2.converter.scalars.ScalarsConverterFactory; public class RetrofitClient { - private Retrofit retrofit; + private static final Map apiInterfaces = new ConcurrentHashMap<>(); + private static final Map webInterfaces = new ConcurrentHashMap<>(); - private RetrofitClient(String instanceUrl, Context ctx) { + private static Retrofit createRetrofit(Context context, String instanceUrl) { - TinyDB tinyDb = new TinyDB(ctx); - final boolean connToInternet = AppUtil.hasNetworkConnection(ctx); - int cacheSize = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeStr")) * 1024 * 1024; - File httpCacheDirectory = new File(ctx.getCacheDir(), "responses"); - Cache cache = new Cache(httpCacheDirectory, cacheSize); + TinyDB tinyDB = TinyDB.getInstance(context); + + int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024; + Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize); HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); @@ -44,47 +46,80 @@ public class RetrofitClient { SSLContext sslContext = SSLContext.getInstance("TLS"); - MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(ctx); - sslContext.init(null, new X509TrustManager[]{memorizingTrustManager}, new SecureRandom()); + MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(context); + sslContext.init(null, new X509TrustManager[]{ memorizingTrustManager }, new SecureRandom()); OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder().cache(cache) - //.addInterceptor(logging) - .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager).hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())).addInterceptor(chain -> { + //.addInterceptor(logging) + .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) + .hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())) + .addInterceptor(chain -> { - Request request = chain.request(); - if(connToInternet) { - request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build(); - } - else { - request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); - } - return chain.proceed(request); - }); + Request request = chain.request(); - Retrofit.Builder builder = new Retrofit.Builder().baseUrl(instanceUrl).client(okHttpClient.build()).addConverterFactory(ScalarsConverterFactory.create()).addConverterFactory(GsonConverterFactory.create()); + request = AppUtil.hasNetworkConnection(context) ? + request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build() : + request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build(); - retrofit = builder.build(); + return chain.proceed(request); + + }); + + return new Retrofit.Builder() + .baseUrl(instanceUrl) + .client(okHttpClient.build()) + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .build(); } catch(Exception e) { - Log.e("onFailure", e.toString()); + + Log.e("onFailureRetrofit", e.toString()); } + return null; } - public static synchronized RetrofitClient getInstance(String instanceUrl, Context ctx) { + public static ApiInterface getApiInterface(Context context) { - return new RetrofitClient(instanceUrl, ctx); + return getApiInterface(context, TinyDB.getInstance(context).getString("instanceUrl")); } - public ApiInterface getApiInterface() { + public static WebInterface getWebInterface(Context context) { + + String instanceUrl = TinyDB.getInstance(context).getString("instanceUrl"); + instanceUrl = instanceUrl.substring(0, instanceUrl.lastIndexOf("api/v1/")); + + return getWebInterface(context, instanceUrl); - return retrofit.create(ApiInterface.class); } - public WebInterface getWebInterface() { + public static ApiInterface getApiInterface(Context context, String url) { + if(!apiInterfaces.containsKey(url)) { - return retrofit.create(WebInterface.class); + ApiInterface apiInterface = createRetrofit(context, url) + .create(ApiInterface.class); + + apiInterfaces.put(url, apiInterface); + return apiInterface; + + } + + return apiInterfaces.get(url); } + public static WebInterface getWebInterface(Context context, String url) { + if(!webInterfaces.containsKey(url)) { + + WebInterface webInterface = createRetrofit(context, url) + .create(WebInterface.class); + + webInterfaces.put(url, webInterface); + return webInterface; + + } + + return webInterfaces.get(url); + } } diff --git a/app/src/main/java/org/mian/gitnex/database/api/DraftsApi.java b/app/src/main/java/org/mian/gitnex/database/api/DraftsApi.java index 61733dd2..fd3fd691 100644 --- a/app/src/main/java/org/mian/gitnex/database/api/DraftsApi.java +++ b/app/src/main/java/org/mian/gitnex/database/api/DraftsApi.java @@ -27,7 +27,7 @@ public class DraftsApi { draftsDao = db.draftsDao(); } - public long insertDraft(int repositoryId, int draftAccountId, int issueId, String draftText, String draftType, String commentId) { + public long insertDraft(int repositoryId, int draftAccountId, int issueId, String draftText, String draftType, String commentId, String issueType) { Draft draft = new Draft(); draft.setDraftRepositoryId(repositoryId); @@ -35,7 +35,8 @@ public class DraftsApi { draft.setIssueId(issueId); draft.setDraftText(draftText); draft.setDraftType(draftType); - draft.setCommentId(draftType); + draft.setCommentId(commentId); + draft.setIssueType(issueType); return insertDraftAsyncTask(draft); } @@ -50,7 +51,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsRepository, e.toString()); + Log.e(StaticGlobalVariables.draftsApi, e.toString()); } return draftId; @@ -66,7 +67,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsRepository, e.toString()); + Log.e(StaticGlobalVariables.draftsApi, e.toString()); } return draftId; @@ -82,7 +83,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsRepository, e.toString()); + Log.e(StaticGlobalVariables.draftsApi, e.toString()); } return checkDraftFlag; diff --git a/app/src/main/java/org/mian/gitnex/database/api/RepositoriesApi.java b/app/src/main/java/org/mian/gitnex/database/api/RepositoriesApi.java index 82f1c66d..55fd537c 100644 --- a/app/src/main/java/org/mian/gitnex/database/api/RepositoriesApi.java +++ b/app/src/main/java/org/mian/gitnex/database/api/RepositoriesApi.java @@ -47,7 +47,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesRepository, e.toString()); + Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); } return repositoryId; @@ -63,7 +63,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesRepository, e.toString()); + Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); } return repository; @@ -89,7 +89,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesRepository, e.toString()); + Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); } return checkRepository; @@ -105,7 +105,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesRepository, e.toString()); + Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); } return repository; @@ -121,7 +121,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesRepository, e.toString()); + Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); } return repository; diff --git a/app/src/main/java/org/mian/gitnex/database/api/UserAccountsApi.java b/app/src/main/java/org/mian/gitnex/database/api/UserAccountsApi.java index 23ba5831..92e7f183 100644 --- a/app/src/main/java/org/mian/gitnex/database/api/UserAccountsApi.java +++ b/app/src/main/java/org/mian/gitnex/database/api/UserAccountsApi.java @@ -17,6 +17,7 @@ public class UserAccountsApi { private static UserAccountsDao userAccountsDao; private static UserAccount userAccount; + private static List userAccounts; private static Integer checkAccount; private static long accountId; @@ -49,7 +50,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsRepository, e.toString()); + Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); } return accountId; @@ -80,7 +81,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsRepository, e.toString()); + Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); } return userAccount; @@ -96,7 +97,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsRepository, e.toString()); + Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); } return checkAccount; @@ -107,6 +108,22 @@ public class UserAccountsApi { return userAccountsDao.fetchAllAccounts(); } + public List usersAccounts() { + + try { + + Thread thread = new Thread(() -> userAccounts = userAccountsDao.userAccounts()); + thread.start(); + thread.join(); + } + catch(InterruptedException e) { + + Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); + } + + return userAccounts; + } + public void deleteAccount(final int accountId) { new Thread(() -> userAccountsDao.deleteAccount(accountId)).start(); diff --git a/app/src/main/java/org/mian/gitnex/database/dao/UserAccountsDao.java b/app/src/main/java/org/mian/gitnex/database/dao/UserAccountsDao.java index 64d05209..9abad2db 100644 --- a/app/src/main/java/org/mian/gitnex/database/dao/UserAccountsDao.java +++ b/app/src/main/java/org/mian/gitnex/database/dao/UserAccountsDao.java @@ -20,6 +20,9 @@ public interface UserAccountsDao { @Query("SELECT * FROM UserAccounts ORDER BY accountId ASC") LiveData> fetchAllAccounts(); + @Query("SELECT * FROM UserAccounts ORDER BY accountId ASC") + List userAccounts(); + @Query("SELECT COUNT(accountId) FROM UserAccounts WHERE accountName = :accountName") Integer getCount(String accountName); diff --git a/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java b/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java index 4dfb1634..3669d8ea 100644 --- a/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java +++ b/app/src/main/java/org/mian/gitnex/database/db/GitnexDatabase.java @@ -19,7 +19,7 @@ import org.mian.gitnex.database.models.UserAccount; */ @Database(entities = {Draft.class, Repository.class, UserAccount.class}, - version = 2, exportSchema = false) + version = 3, exportSchema = false) public abstract class GitnexDatabase extends RoomDatabase { private static GitnexDatabase gitnexDatabase; @@ -27,10 +27,11 @@ public abstract class GitnexDatabase extends RoomDatabase { public static GitnexDatabase getDatabaseInstance(Context context) { if (gitnexDatabase == null) { + String DB_NAME = "gitnex"; gitnexDatabase = Room.databaseBuilder(context, GitnexDatabase.class, DB_NAME) //.fallbackToDestructiveMigration() - .addMigrations(MIGRATION_1_2) + .addMigrations(MIGRATION_1_2, MIGRATION_2_3) .build(); } @@ -49,7 +50,14 @@ public abstract class GitnexDatabase extends RoomDatabase { //database.execSQL("DROP TABLE Drafts"); database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'commentId' TEXT"); - } }; + + private static final Migration MIGRATION_2_3 = new Migration(2, 3) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + + database.execSQL("ALTER TABLE 'Drafts' ADD COLUMN 'issueType' TEXT"); + } + }; } diff --git a/app/src/main/java/org/mian/gitnex/database/models/Draft.java b/app/src/main/java/org/mian/gitnex/database/models/Draft.java index aaf36af9..4792354c 100644 --- a/app/src/main/java/org/mian/gitnex/database/models/Draft.java +++ b/app/src/main/java/org/mian/gitnex/database/models/Draft.java @@ -26,6 +26,8 @@ public class Draft implements Serializable { private String draftType; @Nullable private String commentId; + @Nullable + private String issueType; public int getDraftId() { @@ -99,4 +101,15 @@ public class Draft implements Serializable { this.commentId = commentId; } + @Nullable + public String getIssueType() { + + return issueType; + } + + public void setIssueType(@Nullable String issueType) { + + this.issueType = issueType; + } + } diff --git a/app/src/main/java/org/mian/gitnex/database/models/DraftWithRepository.java b/app/src/main/java/org/mian/gitnex/database/models/DraftWithRepository.java index 3509edb7..e835cb7e 100644 --- a/app/src/main/java/org/mian/gitnex/database/models/DraftWithRepository.java +++ b/app/src/main/java/org/mian/gitnex/database/models/DraftWithRepository.java @@ -19,6 +19,7 @@ public class DraftWithRepository { private String draftText; private String draftType; private String commentId; + private String issueType; public int getRepositoryId() { @@ -130,4 +131,14 @@ public class DraftWithRepository { this.commentId = commentId; } + public String getIssueType() { + + return issueType; + } + + public void setIssueType(String issueType) { + + this.issueType = issueType; + } + } diff --git a/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java b/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java index 9f43bd12..c26aeb9f 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java @@ -24,7 +24,7 @@ public class AboutFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { FragmentAboutBinding viewBinding = FragmentAboutBinding.inflate(inflater, container, false); - TinyDB tinyDb = new TinyDB(getContext()); + TinyDB tinyDb = TinyDB.getInstance(getContext()); viewBinding.appVersion.setText(AppUtil.getAppVersion(requireContext())); viewBinding.userServerVersion.setText(tinyDb.getString("giteaVersion")); @@ -32,15 +32,6 @@ public class AboutFragment extends Fragment { ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.pageTitleAbout)); - viewBinding.donationLinkLiberapay.setOnClickListener(v1 -> { - - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_VIEW); - intent.addCategory(Intent.CATEGORY_BROWSABLE); - intent.setData(Uri.parse(getResources().getString(R.string.supportLink))); - startActivity(intent); - }); - viewBinding.donationLinkPatreon.setOnClickListener(v12 -> { Intent intent = new Intent(); @@ -72,7 +63,6 @@ public class AboutFragment extends Fragment { viewBinding.supportHeader.setVisibility(View.GONE); viewBinding.dividerSupport.setVisibility(View.GONE); - viewBinding.donationLinkLiberapay.setVisibility(View.GONE); viewBinding.donationLinkPatreon.setVisibility(View.GONE); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/AdministrationFragment.java b/app/src/main/java/org/mian/gitnex/fragments/AdministrationFragment.java index 6492c03b..7b496d6a 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/AdministrationFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/AdministrationFragment.java @@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import org.mian.gitnex.R; import org.mian.gitnex.activities.AdminGetUsersActivity; -import org.mian.gitnex.helpers.TinyDB; /** * Author M M Arif @@ -23,8 +22,6 @@ public class AdministrationFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_administration, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - TextView adminUsers = v.findViewById(R.id.adminUsers); adminUsers.setOnClickListener(v1 -> startActivity(new Intent(getContext(), AdminGetUsersActivity.class))); diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetNotificationsFilterFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetNotificationsFilterFragment.java index 48b66560..f8675d88 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetNotificationsFilterFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetNotificationsFilterFragment.java @@ -24,7 +24,7 @@ public class BottomSheetNotificationsFilterFragment extends BottomSheetDialogFra @Override public void onAttach(@NonNull Context context) { - this.tinyDB = new TinyDB(context); + this.tinyDB = TinyDB.getInstance(context); super.onAttach(context); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java index e9629618..322f039c 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetOrganizationFragment.java @@ -28,6 +28,7 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment { TextView createTeam = v.findViewById(R.id.createTeam); TextView createRepository = v.findViewById(R.id.createRepository); TextView copyOrgUrl = v.findViewById(R.id.copyOrgUrl); + TextView createLabel = v.findViewById(R.id.createLabel); createTeam.setOnClickListener(v1 -> { @@ -35,6 +36,12 @@ public class BottomSheetOrganizationFragment extends BottomSheetDialogFragment { dismiss(); }); + createLabel.setOnClickListener(v1 -> { + + bmListener.onButtonClicked("label"); + dismiss(); + }); + createRepository.setOnClickListener(v12 -> { bmListener.onButtonClicked("repository"); diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java index e3dbd1b5..986ffa3f 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java @@ -1,12 +1,14 @@ package org.mian.gitnex.fragments; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; @@ -14,6 +16,8 @@ import android.widget.ImageButton; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.mian.gitnex.R; import org.mian.gitnex.actions.ActionResult; @@ -31,6 +35,9 @@ import java.util.Objects; public class BottomSheetReplyFragment extends BottomSheetDialogFragment { + private enum Mode { EDIT, SEND } + private Mode mode = Mode.SEND; + private TinyDB tinyDB; private DraftsApi draftsApi; @@ -39,12 +46,13 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { private int issueNumber; private long draftId; + private OnInteractedListener onInteractedListener; private TextView draftsHint; @Override public void onAttach(@NonNull Context context) { - tinyDB = new TinyDB(context); + tinyDB = TinyDB.getInstance(context); draftsApi = new DraftsApi(context); repositoryId = (int) tinyDB.getLong("repositoryId", 0); @@ -54,6 +62,7 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { super.onAttach(context); } + @SuppressLint("ClickableViewAccessibility") @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -63,7 +72,7 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { draftsHint = view.findViewById(R.id.drafts_hint); - EditText commentContent = view.findViewById(R.id.comment); + EditText comment = view.findViewById(R.id.comment); TextView toolbarTitle = view.findViewById(R.id.toolbar_title); ImageButton close = view.findViewById(R.id.close); ImageButton drafts = view.findViewById(R.id.drafts); @@ -71,9 +80,12 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { send.setEnabled(false); - if(Objects.equals(arguments.getString("commentAction"), "edit")) { + if(Objects.equals(arguments.getString("commentAction"), "edit") && + arguments.getString("draftId") == null) { + + send.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_save)); + mode = Mode.EDIT; - send.setVisibility(View.GONE); } if(arguments.getString("draftId") != null) { @@ -95,21 +107,40 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { send.setEnabled(true); send.setAlpha(1f); - commentContent.setText(arguments.getString("commentBody")); + comment.setText(arguments.getString("commentBody")); if(arguments.getBoolean("cursorToEnd", false)) { - commentContent.setSelection(commentContent.length()); + comment.setSelection(comment.length()); } } - commentContent.requestFocus(); - commentContent.addTextChangedListener(new TextWatcher() { + comment.requestFocus(); + comment.setOnTouchListener((v, event) -> { + + BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from((View) view.getParent()); + + switch(event.getAction()) { + + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_SCROLL: + bottomSheetBehavior.setDraggable(false); + break; + + default: + bottomSheetBehavior.setDraggable(true); + } + + return false; + + }); + + comment.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { - String text = commentContent.getText().toString(); + String text = comment.getText().toString(); if(text.isEmpty()) { @@ -127,6 +158,7 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} + }); close.setOnClickListener(v -> dismiss()); @@ -138,33 +170,69 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { startActivity(intent); dismiss(); + }); - send.setOnClickListener(v -> IssueActions - .reply(getContext(), commentContent.getText().toString(), issueNumber) - .accept((status, result) -> { + send.setOnClickListener(v -> { - if(status == ActionResult.Status.SUCCESS) { + if(mode == Mode.SEND) { - Toasty.success(getContext(), getString(R.string.commentSuccess)); + IssueActions + .reply(getContext(), comment.getText().toString(), issueNumber) + .accept((status, result) -> { - tinyDB.putBoolean("commentPosted", true); - tinyDB.putBoolean("resumeIssues", true); - tinyDB.putBoolean("resumePullRequests", true); + if(status == ActionResult.Status.SUCCESS) { - if(draftId != 0 && tinyDB.getBoolean("draftsCommentsDeletionEnabled")) { + Toasty.success(getContext(), getString(R.string.commentSuccess)); - draftsApi.deleteSingleDraft((int) draftId); - } + if(draftId != 0 && tinyDB.getBoolean("draftsCommentsDeletionEnabled")) { + draftsApi.deleteSingleDraft((int) draftId); + } - dismiss(); - } - else { + tinyDB.putBoolean("commentPosted", true); + tinyDB.putBoolean("resumeIssues", true); + tinyDB.putBoolean("resumePullRequests", true); - Toasty.error(getContext(), getString(R.string.commentError)); - dismiss(); - } - })); + if(onInteractedListener != null) { + onInteractedListener.onInteracted(); + } + } + else { + + Toasty.error(getContext(), getString(R.string.commentError)); + } + + dismiss(); + + }); + } else { + + IssueActions + .edit(getContext(), comment.getText().toString(), arguments.getInt("commentId")) + .accept((status, result) -> { + + if(status == ActionResult.Status.SUCCESS) { + + if(draftId != 0 && tinyDB.getBoolean("draftsCommentsDeletionEnabled")) { + draftsApi.deleteSingleDraft((int) draftId); + } + + tinyDB.putBoolean("commentEdited", true); + + if(onInteractedListener != null) { + onInteractedListener.onInteracted(); + } + } + else { + + Toasty.error(getContext(), getString(R.string.genericError)); + } + + dismiss(); + + }); + } + }); return view; } @@ -193,9 +261,26 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { } else { + String draftType; + if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) { + + draftType = StaticGlobalVariables.draftTypeIssue; + } + else if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { + + draftType = StaticGlobalVariables.draftTypePull; + } + else { + + draftType = ""; + } + if(draftId == 0) { - draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, text, StaticGlobalVariables.draftTypeComment, "TODO"); - } else { + + draftId = draftsApi.insertDraft(repositoryId, currentActiveAccountId, issueNumber, text, draftType, "TODO", tinyDB.getString("issueType")); + } + else { + DraftsApi.updateDraft(text, (int) draftId, "TODO"); } @@ -211,4 +296,12 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { return fragment; } + + public void setOnInteractedListener(OnInteractedListener onInteractedListener) { + + this.onInteractedListener = onInteractedListener; + } + + public interface OnInteractedListener { void onInteracted(); } + } diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java index f99ea3a1..f04a2359 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetRepoFragment.java @@ -26,7 +26,7 @@ public class BottomSheetRepoFragment extends BottomSheetDialogFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.bottom_sheet_repo, container, false); - final TinyDB tinyDb = new TinyDB(getContext()); + final TinyDB tinyDb = TinyDB.getInstance(getContext()); TextView createLabel = v.findViewById(R.id.createLabel); TextView createIssue = v.findViewById(R.id.createNewIssue); 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 bd936948..dcf70c3e 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java @@ -8,6 +8,7 @@ import android.os.Bundle; 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.annotation.Nullable; @@ -20,6 +21,7 @@ import org.mian.gitnex.activities.MergePullRequestActivity; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; +import org.mian.gitnex.views.ReactionSpinner; import java.util.Objects; /** @@ -37,7 +39,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { View v = inflater.inflate(R.layout.bottom_sheet_single_issue, container, false); final Context ctx = getContext(); - final TinyDB tinyDB = new TinyDB(ctx); + final TinyDB tinyDB = TinyDB.getInstance(ctx); TextView editIssue = v.findViewById(R.id.editIssue); TextView editLabels = v.findViewById(R.id.editLabels); @@ -51,6 +53,29 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { TextView subscribeIssue = v.findViewById(R.id.subscribeIssue); TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue); + LinearLayout linearLayout = v.findViewById(R.id.commentReactionButtons); + + Bundle bundle1 = new Bundle(); + + String repoFullName = tinyDB.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + + bundle1.putString("repoOwner", parts[0]); + bundle1.putString("repoName", parts[1]); + bundle1.putInt("issueId", Integer.parseInt(tinyDB.getString("issueNumber"))); + + ReactionSpinner reactionSpinner = new ReactionSpinner(ctx, bundle1); + reactionSpinner.setOnInteractedListener(() -> { + + tinyDB.putBoolean("singleIssueUpdate", true); + + bmListener.onButtonClicked("onResume"); + dismiss(); + + }); + + linearLayout.addView(reactionSpinner); + if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { editIssue.setText(R.string.editPrText); diff --git a/app/src/main/java/org/mian/gitnex/fragments/CollaboratorsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/CollaboratorsFragment.java index ffb764af..6de7256a 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/CollaboratorsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/CollaboratorsFragment.java @@ -16,7 +16,6 @@ import androidx.lifecycle.ViewModelProvider; import org.mian.gitnex.R; import org.mian.gitnex.adapters.CollaboratorsAdapter; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.viewmodels.CollaboratorsViewModel; import java.util.List; @@ -65,18 +64,12 @@ public class CollaboratorsFragment extends Fragment { Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_collaborators, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + noDataCollaborators = v.findViewById(R.id.noDataCollaborators); - mProgressBar = v.findViewById(R.id.progress_bar); - mGridView = v.findViewById(R.id.gridView); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); - + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName); return v; } @@ -96,11 +89,11 @@ public class CollaboratorsFragment extends Fragment { void onFragmentInteraction(Uri uri); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { + private void fetchDataAsync(String instanceToken, String owner, String repo) { CollaboratorsViewModel collaboratorsModel = new ViewModelProvider(this).get(CollaboratorsViewModel.class); - collaboratorsModel.getCollaboratorsList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + collaboratorsModel.getCollaboratorsList(instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List collaboratorsListMain) { adapter = new CollaboratorsAdapter(getContext(), collaboratorsListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java index bda08766..699fa4e6 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java @@ -20,6 +20,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.DraftsAdapter; import org.mian.gitnex.database.api.DraftsApi; import org.mian.gitnex.database.models.DraftWithRepository; @@ -51,7 +52,9 @@ public class DraftsFragment extends Fragment { ctx = getContext(); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(ctx); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.titleDrafts)); + + TinyDB tinyDb = TinyDB.getInstance(ctx); draftsList_ = new ArrayList<>(); draftsApi = new DraftsApi(ctx); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java index 47d3c23e..b0162e7e 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java @@ -36,7 +36,7 @@ public class ExploreFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_explore, container,false); ctx = getContext(); - tinyDB = new TinyDB(ctx); + tinyDB = TinyDB.getInstance(ctx); ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navExplore)); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java index 75bf2c84..d55590a9 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java @@ -17,6 +17,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import org.mian.gitnex.R; import org.mian.gitnex.adapters.ExploreRepositoriesAdapter; @@ -57,10 +58,6 @@ public class ExploreRepositoriesFragment extends Fragment { private List dataList; private ExploreRepositoriesAdapter adapter; - private String instanceUrl; - private String loginUid; - private String instanceToken; - private Dialog dialogFilterOptions; private CustomExploreRepositoriesDialogBinding filterBinding; @@ -71,11 +68,7 @@ public class ExploreRepositoriesFragment extends Fragment { setHasOptionsMenu(true); ctx = getContext(); - tinyDb = new TinyDB(getContext()); - - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + tinyDb = TinyDB.getInstance(getContext()); dataList = new ArrayList<>(); adapter = new ExploreRepositoriesAdapter(dataList, ctx); @@ -96,6 +89,10 @@ public class ExploreRepositoriesFragment extends Fragment { viewBinding.recyclerViewReposSearch.setLayoutManager(linearLayoutManager); viewBinding.recyclerViewReposSearch.setAdapter(adapter); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerViewReposSearch.getContext(), + DividerItemDecoration.VERTICAL); + viewBinding.recyclerViewReposSearch.addItemDecoration(dividerItemDecoration); + viewBinding.searchKeyword.setOnEditorActionListener((v1, actionId, event) -> { if(actionId == EditorInfo.IME_ACTION_SEND) { @@ -178,7 +175,7 @@ public class ExploreRepositoriesFragment extends Fragment { viewBinding.loadingMoreView.setVisibility(View.VISIBLE); } - Call call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryRepos(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, repoTypeInclude, sort, order, exploreRepoIncludeTopic, exploreRepoIncludeDescription, exploreRepoIncludeTemplate, exploreRepoOnlyArchived, limit, pageCurrentIndex); + Call call = RetrofitClient.getApiInterface(ctx).queryRepos(Authorization.get(getContext()), searchKeyword, repoTypeInclude, sort, order, exploreRepoIncludeTopic, exploreRepoIncludeDescription, exploreRepoIncludeTemplate, exploreRepoOnlyArchived, limit, pageCurrentIndex); call.enqueue(new Callback() { 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 c9e061e0..d696d637 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java @@ -26,7 +26,6 @@ import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.FilesAdapter; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.viewmodels.FilesViewModel; import java.util.ArrayList; import java.util.Collections; @@ -89,11 +88,6 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter View v = inflater.inflate(R.layout.fragment_files, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - noDataFiles = v.findViewById(R.id.noDataFiles); filesFrame = v.findViewById(R.id.filesFrame); @@ -115,11 +109,11 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter fileStructure.setText(""); ref = repoBranch; mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, repoBranch); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, repoBranch); }); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, ref); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref); return v; } @@ -133,11 +127,6 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter @Override public void onClickDir(String dirName) { - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - StringBuilder breadcrumbBuilder = new StringBuilder(); breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); @@ -158,7 +147,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter if(position == 0) { - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, ref); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref); fileStructure.setText(""); return; } @@ -169,7 +158,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter String currentIndex = (result + item.getSelectedItem()).substring(1); - fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, currentIndex, ref); + fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, currentIndex, ref); } @@ -179,7 +168,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter } }); - fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, finalDirName_, ref); + fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, finalDirName_, ref); } @@ -200,14 +189,14 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter requireContext().startActivity(intent); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo, String ref) { + private void fetchDataAsync(String instanceToken, String owner, String repo, String ref) { mRecyclerView.setVisibility(View.GONE); mProgressBar.setVisibility(View.VISIBLE); FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { + filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); mBreadcrumbsView.removeItemAfter(1); @@ -231,14 +220,14 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter } - private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir, String ref) { + private void fetchDataAsyncSub(String instanceToken, String owner, String repo, String filesDir, String ref) { mRecyclerView.setVisibility(View.GONE); mProgressBar.setVisibility(View.VISIBLE); FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, ref, getContext(), mProgressBar, noDataFiles).observe(this, filesListMain2 -> { + filesModel2.getFilesList2(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/fragments/IssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java index 0fbcf14d..1655d101 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java @@ -17,19 +17,19 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.IssuesAdapter; -import org.mian.gitnex.clients.AppApiService; +import org.mian.gitnex.clients.RetrofitClient; 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.Issues; import java.util.ArrayList; import java.util.List; @@ -47,7 +47,6 @@ public class IssuesFragment extends Fragment { private RecyclerView recyclerView; private List issuesList; private IssuesAdapter adapter; - private ApiInterface api; private Context context; private int pageSize = StaticGlobalVariables.issuesPageInit; private ProgressBar mProgressBar; @@ -65,12 +64,11 @@ public class IssuesFragment extends Fragment { setHasOptionsMenu(true); context = getContext(); - TinyDB tinyDb = new TinyDB(getContext()); + TinyDB tinyDb = TinyDB.getInstance(getContext()); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); @@ -102,13 +100,15 @@ public class IssuesFragment extends Fragment { if(issuesList.size() == resultLimit || pageSize == resultLimit) { int page = (issuesList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState")); } })); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL); recyclerView.setHasFixedSize(true); + recyclerView.addItemDecoration(dividerItemDecoration); recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setAdapter(adapter); @@ -129,7 +129,7 @@ public class IssuesFragment extends Fragment { if(issuesList.size() == resultLimit || pageSize == resultLimit) { int page = (issuesList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState")); } @@ -140,13 +140,12 @@ public class IssuesFragment extends Fragment { mProgressBar.setVisibility(View.VISIBLE); noDataIssues.setVisibility(View.GONE); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, issueState); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, issueState); recyclerView.setAdapter(adapter); }); - api = AppApiService.createService(ApiInterface.class, instanceUrl, getContext()); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); return v; @@ -156,17 +155,16 @@ public class IssuesFragment extends Fragment { public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String loginUid = tinyDb.getString("loginUid"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); + 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"); if(tinyDb.getBoolean("resumeIssues")) { - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); tinyDb.putBoolean("resumeIssues", false); } @@ -175,7 +173,7 @@ public class IssuesFragment extends Fragment { private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType, String issueState) { - Call> call = api.getIssues(token, repoOwner, repoName, 1, resultLimit, requestType, issueState); + Call> call = RetrofitClient.getApiInterface(context).getIssues(token, repoOwner, repoName, 1, resultLimit, requestType, issueState); call.enqueue(new Callback>() { @@ -230,7 +228,7 @@ public class IssuesFragment extends Fragment { progressLoadMore.setVisibility(View.VISIBLE); - Call> call = api.getIssues(token, repoOwner, repoName, page, resultLimit, requestType, issueState); + Call> call = RetrofitClient.getApiInterface(context).getIssues(token, repoOwner, repoName, page, resultLimit, requestType, issueState); call.enqueue(new Callback>() { @@ -285,7 +283,7 @@ public class IssuesFragment extends Fragment { inflater.inflate(R.menu.filter_menu, menu); super.onCreateOptionsMenu(menu, inflater); - TinyDB tinyDb = new TinyDB(context); + TinyDB tinyDb = TinyDB.getInstance(context); if(tinyDb.getString("repoIssuesState").equals("closed")) { menu.getItem(1).setIcon(R.drawable.ic_filter_closed); diff --git a/app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java index 13d1da1f..d994cea5 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java @@ -10,9 +10,7 @@ import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -22,9 +20,7 @@ import org.mian.gitnex.R; import org.mian.gitnex.adapters.LabelsAdapter; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.Labels; import org.mian.gitnex.viewmodels.LabelsViewModel; -import java.util.List; /** * Author M M Arif @@ -38,6 +34,7 @@ public class LabelsFragment extends Fragment { private TextView noData; private static String repoNameF = "param2"; private static String repoOwnerF = "param1"; + private final String type = "repo"; private String repoName; private String repoOwner; @@ -48,6 +45,7 @@ public class LabelsFragment extends Fragment { } public static LabelsFragment newInstance(String param1, String param2) { + LabelsFragment fragment = new LabelsFragment(); Bundle args = new Bundle(); args.putString(repoOwnerF, param1); @@ -58,8 +56,11 @@ public class LabelsFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + repoName = getArguments().getString(repoNameF); repoOwner = getArguments().getString(repoOwnerF); } @@ -71,10 +72,6 @@ public class LabelsFragment extends Fragment { final View v = inflater.inflate(R.layout.fragment_labels, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); noData = v.findViewById(R.id.noData); @@ -91,69 +88,73 @@ public class LabelsFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext()); - + LabelsViewModel.loadLabelsList(Authorization.get(getContext()), repoOwner, repoName, getContext()); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName); return v; - } @Override public void onResume() { + super.onResume(); - final TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); + final TinyDB tinyDb = TinyDB.getInstance(getContext()); + 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"); if(tinyDb.getBoolean("labelsRefresh")) { - LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext()); + + LabelsViewModel.loadLabelsList(Authorization.get(getContext()), repoOwner, repoName, getContext()); tinyDb.putBoolean("labelsRefresh", false); } } public void onButtonPressed(Uri uri) { + if (mListener != null) { + mListener.onFragmentInteraction(uri); } } @Override public void onDetach() { + super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { + void onFragmentInteraction(Uri uri); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { + private void fetchDataAsync(String instanceToken, String owner, String repo) { LabelsViewModel labelsModel = new ViewModelProvider(this).get(LabelsViewModel.class); - labelsModel.getLabelsList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List labelsListMain) { - adapter = new LabelsAdapter(getContext(), labelsListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noData.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noData.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); + labelsModel.getLabelsList(instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), labelsListMain -> { + + adapter = new LabelsAdapter(getContext(), labelsListMain, type, owner); + + if(adapter.getItemCount() > 0) { + + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.GONE); } + else { + + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.VISIBLE); + } + + mProgressBar.setVisibility(View.GONE); }); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/MembersByOrgFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MembersByOrgFragment.java index c763ab93..b27e7f0f 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MembersByOrgFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MembersByOrgFragment.java @@ -68,8 +68,7 @@ public class MembersByOrgFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_members_by_org, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); noDataMembers = v.findViewById(R.id.noDataMembers); @@ -77,16 +76,16 @@ public class MembersByOrgFragment extends Fragment { progressBar = v.findViewById(R.id.progressBar); mGridView = v.findViewById(R.id.gridView); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName); + fetchDataAsync(Authorization.get(getContext()), orgName); return v; } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) { + private void fetchDataAsync(String instanceToken, String owner) { MembersByOrgViewModel membersModel= new ViewModelProvider(this).get(MembersByOrgViewModel.class); - membersModel.getMembersList(instanceUrl, instanceToken, owner, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + membersModel.getMembersList(instanceToken, owner, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List membersListMain) { adapter = new MembersByOrgAdapter(getContext(), membersListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java index 0ee28723..b1a0d9d2 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java @@ -14,17 +14,17 @@ import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import org.mian.gitnex.R; import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.MilestonesAdapter; -import org.mian.gitnex.clients.AppApiService; +import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.FragmentMilestonesBinding; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Version; -import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.models.Milestones; import java.util.ArrayList; import java.util.List; @@ -43,7 +43,6 @@ public class MilestonesFragment extends Fragment { private Menu menu; private List dataList; private MilestonesAdapter adapter; - private ApiInterface api; private Context ctx; private int pageSize = StaticGlobalVariables.milestonesPageInit; private String TAG = StaticGlobalVariables.tagMilestonesFragment; @@ -56,12 +55,11 @@ public class MilestonesFragment extends Fragment { setHasOptionsMenu(true); ctx = getContext(); - TinyDB tinyDb = new TinyDB(getContext()); + TinyDB tinyDb = TinyDB.getInstance(getContext()); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); @@ -83,7 +81,7 @@ public class MilestonesFragment extends Fragment { if(dataList.size() == resultLimit || pageSize == resultLimit) { int page = (dataList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState")); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState")); } @@ -91,6 +89,8 @@ public class MilestonesFragment extends Fragment { } + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerView.getContext(), DividerItemDecoration.VERTICAL); + viewBinding.recyclerView.addItemDecoration(dividerItemDecoration); viewBinding.recyclerView.setHasFixedSize(true); viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); viewBinding.recyclerView.setAdapter(adapter); @@ -99,7 +99,7 @@ public class MilestonesFragment extends Fragment { dataList.clear(); viewBinding.pullToRefresh.setRefreshing(false); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); adapter.updateList(dataList); }, 50)); @@ -124,7 +124,7 @@ public class MilestonesFragment extends Fragment { if(dataList.size() == resultLimit || pageSize == resultLimit) { int page = (dataList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, milestoneState); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, resultLimit, milestoneState); } @@ -137,13 +137,12 @@ public class MilestonesFragment extends Fragment { viewBinding.progressBar.setVisibility(View.VISIBLE); viewBinding.noDataMilestone.setVisibility(View.GONE); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, milestoneState); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, milestoneState); viewBinding.recyclerView.setAdapter(adapter); }); - api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); return viewBinding.getRoot(); @@ -153,7 +152,7 @@ public class MilestonesFragment extends Fragment { public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String loginUid = tinyDb.getString("loginUid"); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); @@ -163,7 +162,7 @@ public class MilestonesFragment extends Fragment { if(tinyDb.getBoolean("milestoneCreated")) { - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); tinyDb.putBoolean("milestoneCreated", false); } @@ -172,7 +171,7 @@ public class MilestonesFragment extends Fragment { private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String milestoneState) { - Call> call = api.getMilestones(token, repoOwner, repoName, 1, resultLimit, milestoneState); + Call> call = RetrofitClient.getApiInterface(ctx).getMilestones(token, repoOwner, repoName, 1, resultLimit, milestoneState); call.enqueue(new Callback>() { @@ -221,7 +220,7 @@ public class MilestonesFragment extends Fragment { viewBinding.progressLoadMore.setVisibility(View.VISIBLE); - Call> call = api.getMilestones(token, repoOwner, repoName, page, resultLimit, milestoneState); + Call> call = RetrofitClient.getApiInterface(ctx).getMilestones(token, repoOwner, repoName, page, resultLimit, milestoneState); call.enqueue(new Callback>() { @@ -278,7 +277,7 @@ public class MilestonesFragment extends Fragment { inflater.inflate(R.menu.filter_menu_milestone, menu); super.onCreateOptionsMenu(menu, inflater); - TinyDB tinyDb = new TinyDB(ctx); + TinyDB tinyDb = TinyDB.getInstance(ctx); if(tinyDb.getString("milestoneState").equals("closed")) { menu.getItem(1).setIcon(R.drawable.ic_filter_closed); diff --git a/app/src/main/java/org/mian/gitnex/fragments/MyRepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyRepositoriesFragment.java index eb26dba3..6392371d 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MyRepositoriesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MyRepositoriesFragment.java @@ -15,9 +15,7 @@ import android.view.inputmethod.EditorInfo; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -26,14 +24,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import org.mian.gitnex.R; import org.mian.gitnex.activities.CreateRepoActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.MyReposListAdapter; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.viewmodels.MyRepositoriesViewModel; -import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -82,20 +77,17 @@ public class MyRepositoriesFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - final View v = inflater.inflate(R.layout.fragment_my_repositories, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String userLogin = tinyDb.getString("userLogin"); tinyDb.putBoolean("isRepoAdmin", true); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navMyRepos)); + noDataMyRepo = v.findViewById(R.id.noDataMyRepo); mProgressBar = v.findViewById(R.id.progress_bar); mRecyclerView = v.findViewById(R.id.recyclerView); @@ -134,11 +126,11 @@ public class MyRepositoriesFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin, getContext(), pageSize, resultLimit); + MyRepositoriesViewModel.loadMyReposList(Authorization.get(getContext()), userLogin, getContext(), pageSize, resultLimit); }, 50)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin, pageSize, resultLimit); + fetchDataAsync(Authorization.get(getContext()), userLogin, pageSize, resultLimit); return v; @@ -147,47 +139,41 @@ public class MyRepositoriesFragment extends Fragment { @Override public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String userLogin = tinyDb.getString("userLogin"); if(tinyDb.getBoolean("repoCreated")) { - MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), userLogin, getContext(), pageSize, resultLimit); + MyRepositoriesViewModel.loadMyReposList(Authorization.get(getContext()), userLogin, getContext(), pageSize, resultLimit); tinyDb.putBoolean("repoCreated", false); } } - private void fetchDataAsync(String instanceUrl, String instanceToken, String userLogin, int pageSize, int resultLimit) { + private void fetchDataAsync(String instanceToken, String userLogin, int pageSize, int resultLimit) { MyRepositoriesViewModel myRepoModel = new ViewModelProvider(this).get(MyRepositoriesViewModel.class); - myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, userLogin, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List myReposListMain) { - adapter = new MyReposListAdapter(getContext(), myReposListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noDataMyRepo.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noDataMyRepo.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); - } - }); + myRepoModel.getCurrentUserRepositories(instanceToken, userLogin, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), + myReposListMain -> { + + adapter = new MyReposListAdapter(getContext(), myReposListMain); + if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); + noDataMyRepo.setVisibility(View.GONE); + } + else { + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noDataMyRepo.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); + }); } @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java index 1fb685d3..5ea65949 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java @@ -80,7 +80,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap activity = requireActivity(); context = getContext(); - tinyDB = new TinyDB(context); + tinyDB = TinyDB.getInstance(context); pageResultLimit = StaticGlobalVariables.getCurrentResultLimit(context); tinyDB.putString("notificationsFilterState", currentFilterMode); @@ -193,7 +193,6 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap loadingMoreView.setVisibility(View.VISIBLE); } - String instanceUrl = tinyDB.getString("instanceUrl"); String loginUid = tinyDB.getString("loginUid"); String instanceToken = "token " + tinyDB.getString(loginUid + "-token"); @@ -201,8 +200,8 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap new String[]{"pinned", "read"} : new String[]{"pinned", "unread"}; - Call> call = RetrofitClient.getInstance(instanceUrl, context) - .getApiInterface() + Call> call = RetrofitClient + .getApiInterface(context) .getNotificationThreads(instanceToken, false, filter, StaticGlobalVariables.defaultOldestTimestamp, "", pageCurrentIndex, pageResultLimit); diff --git a/app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java index 3c107f17..733c0735 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/OrganizationInfoFragment.java @@ -18,7 +18,6 @@ import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.RoundedTransformation; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.Organization; import retrofit2.Call; import retrofit2.Callback; @@ -67,11 +66,6 @@ public class OrganizationInfoFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_organization_info, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - mProgressBar = v.findViewById(R.id.progress_bar); orgAvatar = v.findViewById(R.id.orgAvatar); TextView orgNameInfo = v.findViewById(R.id.orgNameInfo); @@ -82,17 +76,16 @@ public class OrganizationInfoFragment extends Fragment { orgNameInfo.setText(orgName); - getOrgInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName); + getOrgInfo(Authorization.get(getContext()), orgName); return v; } - private void getOrgInfo(String instanceUrl, String token, final String owner) { + private void getOrgInfo(String token, final String owner) { Call call = RetrofitClient - .getInstance(instanceUrl, getContext()) - .getApiInterface() + .getApiInterface(getContext()) .getOrganization(token, owner); call.enqueue(new Callback() { diff --git a/app/src/main/java/org/mian/gitnex/fragments/OrganizationLabelsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/OrganizationLabelsFragment.java new file mode 100644 index 00000000..f9908fe0 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/OrganizationLabelsFragment.java @@ -0,0 +1,151 @@ +package org.mian.gitnex.fragments; + +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +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 org.mian.gitnex.R; +import org.mian.gitnex.adapters.LabelsAdapter; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.viewmodels.OrganizationLabelsViewModel; + +/** + * Author M M Arif + */ + +public class OrganizationLabelsFragment extends Fragment { + + private ProgressBar mProgressBar; + private RecyclerView mRecyclerView; + private LabelsAdapter adapter; + private TextView noData; + private static final String repoOwnerF = "param1"; + private final String type = "org"; + + private String repoOwner; + + private OnFragmentInteractionListener mListener; + + public static OrganizationLabelsFragment newInstance(String param1) { + + OrganizationLabelsFragment fragment = new OrganizationLabelsFragment(); + Bundle args = new Bundle(); + args.putString(repoOwnerF, param1); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + + if (getArguments() != null) { + + repoOwner = getArguments().getString(repoOwnerF); + } + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + final View v = inflater.inflate(R.layout.fragment_labels, container, false); + setHasOptionsMenu(true); + + final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + noData = v.findViewById(R.id.noData); + + mRecyclerView = v.findViewById(R.id.recyclerView); + mRecyclerView.setHasFixedSize(true); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), + DividerItemDecoration.VERTICAL); + mRecyclerView.addItemDecoration(dividerItemDecoration); + + mProgressBar = v.findViewById(R.id.progress_bar); + + swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { + + swipeRefresh.setRefreshing(false); + OrganizationLabelsViewModel.loadOrgLabelsList(Authorization.get(getContext()), repoOwner, getContext(), mProgressBar, noData); + + }, 200)); + + fetchDataAsync(Authorization.get(getContext()), repoOwner); + + return v; + + } + + @Override + public void onResume() { + + super.onResume(); + final TinyDB tinyDb = TinyDB.getInstance(getContext()); + + if(tinyDb.getBoolean("labelsRefresh")) { + + OrganizationLabelsViewModel.loadOrgLabelsList(Authorization.get(getContext()), repoOwner, getContext(), mProgressBar, noData); + tinyDb.putBoolean("labelsRefresh", false); + } + } + + public void onButtonPressed(Uri uri) { + + if (mListener != null) { + + mListener.onFragmentInteraction(uri); + } + } + + @Override + public void onDetach() { + + super.onDetach(); + mListener = null; + } + + public interface OnFragmentInteractionListener { + + void onFragmentInteraction(Uri uri); + } + + private void fetchDataAsync(String instanceToken, String owner) { + + OrganizationLabelsViewModel organizationLabelsViewModel = new ViewModelProvider(this).get(OrganizationLabelsViewModel.class); + + organizationLabelsViewModel.getOrgLabelsList(instanceToken, owner, getContext(), mProgressBar, noData).observe(getViewLifecycleOwner(), labelsListMain -> { + + adapter = new LabelsAdapter(getContext(), labelsListMain, type, owner); + + if(adapter.getItemCount() > 0) { + + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.GONE); + } + else { + + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.VISIBLE); + } + + mProgressBar.setVisibility(View.GONE); + }); + + } +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/OrganizationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/OrganizationsFragment.java index 5149ab3e..66766323 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/OrganizationsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/OrganizationsFragment.java @@ -16,7 +16,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -25,14 +24,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import org.mian.gitnex.R; import org.mian.gitnex.activities.CreateOrganizationActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.OrganizationsListAdapter; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserOrganizations; import org.mian.gitnex.viewmodels.OrganizationListViewModel; -import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -53,15 +49,10 @@ public class OrganizationsFragment extends Fragment { final View v = inflater.inflate(R.layout.fragment_organizations, container, false); setHasOptionsMenu(true); - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navOrgs)); + mProgressBar = v.findViewById(R.id.progress_bar); noDataOrg = v.findViewById(R.id.noDataOrg); mRecyclerView = v.findViewById(R.id.recyclerView); @@ -74,14 +65,10 @@ public class OrganizationsFragment extends Fragment { createNewOrganization = v.findViewById(R.id.addNewOrganization); - createNewOrganization.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View view) { - Intent intent = new Intent(view.getContext(), CreateOrganizationActivity.class); - startActivity(intent); - } + createNewOrganization.setOnClickListener(view -> { + Intent intent = new Intent(view.getContext(), CreateOrganizationActivity.class); + startActivity(intent); }); mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -103,11 +90,11 @@ public class OrganizationsFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext()); + OrganizationListViewModel.loadOrgsList(Authorization.get(getContext()), getContext()); }, 50)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken)); + fetchDataAsync(Authorization.get(getContext())); return v; @@ -116,36 +103,33 @@ public class OrganizationsFragment extends Fragment { @Override public void onResume(){ super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); if(tinyDb.getBoolean("orgCreated")) { - OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext()); + OrganizationListViewModel.loadOrgsList(Authorization.get(getContext()), getContext()); tinyDb.putBoolean("orgCreated", false); } } - private void fetchDataAsync(String instanceUrl, String instanceToken) { + private void fetchDataAsync(String instanceToken) { OrganizationListViewModel orgModel = new ViewModelProvider(this).get(OrganizationListViewModel.class); - orgModel.getUserOrgs(instanceUrl, instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List orgsListMain) { - adapter = new OrganizationsListAdapter(getContext(), orgsListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noDataOrg.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noDataOrg.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); + orgModel.getUserOrgs(instanceToken, getContext()).observe(getViewLifecycleOwner(), orgsListMain -> { + adapter = new OrganizationsListAdapter(getContext(), orgsListMain); + + if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); + noDataOrg.setVisibility(View.GONE); } + else { + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noDataOrg.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); }); } @@ -153,8 +137,6 @@ public class OrganizationsFragment extends Fragment { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java index 3b1ca710..40d690f9 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java @@ -20,7 +20,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.adapters.ProfileEmailsAdapter; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.Emails; import org.mian.gitnex.viewmodels.ProfileEmailsViewModel; import java.util.List; @@ -70,11 +69,6 @@ public class ProfileEmailsFragment extends Fragment { final View v = inflater.inflate(R.layout.fragment_profile_emails, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); noDataEmails = v.findViewById(R.id.noDataEmails); @@ -92,21 +86,21 @@ public class ProfileEmailsFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - ProfileEmailsViewModel.loadEmailsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext()); + ProfileEmailsViewModel.loadEmailsList(Authorization.get(getContext()), getContext()); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken)); + fetchDataAsync(Authorization.get(getContext())); return v; } - private void fetchDataAsync(String instanceUrl, String instanceToken) { + private void fetchDataAsync(String instanceToken) { ProfileEmailsViewModel profileEmailModel = new ViewModelProvider(this).get(ProfileEmailsViewModel.class); - profileEmailModel.getEmailsList(instanceUrl, instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + profileEmailModel.getEmailsList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List emailsListMain) { adapter = new ProfileEmailsAdapter(getContext(), emailsListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java index 7a277213..04332e96 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java @@ -21,7 +21,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.adapters.ProfileFollowersAdapter; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.viewmodels.ProfileFollowersViewModel; import java.util.List; @@ -70,11 +69,6 @@ public class ProfileFollowersFragment extends Fragment { Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.fragment_profile_followers, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); noDataFollowers = v.findViewById(R.id.noDataFollowers); @@ -92,20 +86,20 @@ public class ProfileFollowersFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - ProfileFollowersViewModel.loadFollowersList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext()); + ProfileFollowersViewModel.loadFollowersList(Authorization.get(getContext()), getContext()); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken)); + fetchDataAsync(Authorization.get(getContext())); return v; } - private void fetchDataAsync(String instanceUrl, String instanceToken) { + private void fetchDataAsync(String instanceToken) { ProfileFollowersViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowersViewModel.class); - pfModel.getFollowersList(instanceUrl, instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + pfModel.getFollowersList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List pfListMain) { adapter = new ProfileFollowersAdapter(getContext(), pfListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java index 13daf478..6de6974f 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java @@ -70,10 +70,7 @@ public class ProfileFollowingFragment extends Fragment { Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.fragment_profile_following, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); @@ -92,20 +89,20 @@ public class ProfileFollowingFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - ProfileFollowingViewModel.loadFollowingList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext()); + ProfileFollowingViewModel.loadFollowingList(Authorization.get(getContext()), getContext()); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken)); + fetchDataAsync(Authorization.get(getContext())); return v; } - private void fetchDataAsync(String instanceUrl, String instanceToken) { + private void fetchDataAsync(String instanceToken) { ProfileFollowingViewModel pfModel = new ViewModelProvider(this).get(ProfileFollowingViewModel.class); - pfModel.getFollowingList(instanceUrl, instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + pfModel.getFollowingList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List pfListMain) { adapter = new ProfileFollowingAdapter(getContext(), pfListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java index a63a0732..cb08ce87 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java @@ -28,7 +28,6 @@ import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TinyDB; import java.util.Locale; -import java.util.Objects; import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.RenderScriptBlur; @@ -49,7 +48,9 @@ public class ProfileFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_profile, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navProfile)); + + TinyDB tinyDb = TinyDB.getInstance(getContext()); BlurView blurView = v.findViewById(R.id.blurView); TextView userFullName = v.findViewById(R.id.userFullName); @@ -123,15 +124,15 @@ public class ProfileFragment extends Fragment { switch(tinyDb.getInt("customFontId", -1)) { case 0: - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf"); + myTypeface = Typeface.createFromAsset(requireContext().getAssets(), "fonts/roboto.ttf"); break; case 2: - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf"); + myTypeface = Typeface.createFromAsset(requireContext().getAssets(), "fonts/sourcecodeproregular.ttf"); break; default: - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf"); + myTypeface = Typeface.createFromAsset(requireContext().getAssets(), "fonts/manroperegular.ttf"); break; } @@ -203,7 +204,7 @@ public class ProfileFragment extends Fragment { public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { menu.clear(); - Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.profile_dotted_menu, menu); + requireActivity().getMenuInflater().inflate(R.menu.profile_dotted_menu, menu); super.onCreateOptionsMenu(menu, inflater); } diff --git a/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java index 28b1f6ed..805c7d06 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java @@ -24,17 +24,15 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.PullRequestsAdapter; -import org.mian.gitnex.clients.AppApiService; +import org.mian.gitnex.clients.RetrofitClient; 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.PullRequests; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -50,7 +48,6 @@ public class PullRequestsFragment extends Fragment { private RecyclerView recyclerView; private List prList; private PullRequestsAdapter adapter; - private ApiInterface apiPR; private String TAG = StaticGlobalVariables.tagPullRequestsList; private Context context; private int pageSize = StaticGlobalVariables.prPageInit; @@ -66,12 +63,11 @@ public class PullRequestsFragment extends Fragment { setHasOptionsMenu(true); context = getContext(); - TinyDB tinyDb = new TinyDB(getContext()); + TinyDB tinyDb = TinyDB.getInstance(getContext()); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); @@ -100,10 +96,10 @@ public class PullRequestsFragment extends Fragment { adapter = new PullRequestsAdapter(getContext(), prList); adapter.setLoadMoreListener(() -> recyclerView.post(() -> { - if(prList.size() == 10 || pageSize == resultLimit) { + if(prList.size() == resultLimit || pageSize == resultLimit) { int page = (prList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit); } @@ -115,7 +111,7 @@ public class PullRequestsFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setAdapter(adapter); - ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerPr(prState -> { + ((RepoDetailActivity) requireActivity()).setFragmentRefreshListenerPr(prState -> { if(prState.equals("closed")) { menu.getItem(1).setIcon(R.drawable.ic_filter_closed); @@ -129,10 +125,10 @@ public class PullRequestsFragment extends Fragment { adapter = new PullRequestsAdapter(context, prList); adapter.setLoadMoreListener(() -> recyclerView.post(() -> { - if(prList.size() == 10 || pageSize == resultLimit) { + if(prList.size() == resultLimit || pageSize == resultLimit) { int page = (prList.size() + resultLimit) / resultLimit; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit); + loadMore(Authorization.get(getContext()), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit); } @@ -143,14 +139,12 @@ public class PullRequestsFragment extends Fragment { mProgressBar.setVisibility(View.VISIBLE); noData.setVisibility(View.GONE); - loadInitial(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); + loadInitial(Authorization.get(context), repoOwner, repoName, pageSize, prState, resultLimit); recyclerView.setAdapter(adapter); }); - apiPR = AppApiService.createService(ApiInterface.class, instanceUrl, context); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); - + loadInitial(Authorization.get(getContext()), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); return v; } @@ -159,17 +153,16 @@ public class PullRequestsFragment extends Fragment { public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String loginUid = tinyDb.getString("loginUid"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); + 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"); if(tinyDb.getBoolean("resumePullRequests")) { - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); + loadInitial(Authorization.get(getContext()), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); tinyDb.putBoolean("resumePullRequests", false); tinyDb.putBoolean("prMerged", false); @@ -179,7 +172,7 @@ public class PullRequestsFragment extends Fragment { private void loadInitial(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) { - Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); + Call> call = RetrofitClient.getApiInterface(context).getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); call.enqueue(new Callback>() { @@ -238,7 +231,7 @@ public class PullRequestsFragment extends Fragment { progressLoadMore.setVisibility(View.VISIBLE); - Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); + Call> call = RetrofitClient.getApiInterface(context).getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); call.enqueue(new Callback>() { @@ -296,7 +289,7 @@ public class PullRequestsFragment extends Fragment { inflater.inflate(R.menu.filter_menu_pr, menu); super.onCreateOptionsMenu(menu, inflater); - TinyDB tinyDb = new TinyDB(context); + TinyDB tinyDb = TinyDB.getInstance(context); if(tinyDb.getString("repoPrState").equals("closed")) { menu.getItem(1).setIcon(R.drawable.ic_filter_closed); diff --git a/app/src/main/java/org/mian/gitnex/fragments/ReleasesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ReleasesFragment.java index 621ac085..5124335c 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ReleasesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ReleasesFragment.java @@ -71,10 +71,6 @@ public class ReleasesFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_releases, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); noDataReleases = v.findViewById(R.id.noDataReleases); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); @@ -92,11 +88,11 @@ public class ReleasesFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext()); + ReleasesViewModel.loadReleasesList(Authorization.get(getContext()), repoOwner, repoName, getContext()); }, 50)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName); return v; @@ -106,13 +102,10 @@ public class ReleasesFragment extends Fragment { public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); if(tinyDb.getBoolean("updateReleases")) { - ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getContext()); + ReleasesViewModel.loadReleasesList(Authorization.get(getContext()), repoOwner, repoName, getContext()); tinyDb.putBoolean("updateReleases", false); } @@ -134,11 +127,11 @@ public class ReleasesFragment extends Fragment { void onFragmentInteraction(Uri uri); } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { + private void fetchDataAsync(String instanceToken, String owner, String repo) { ReleasesViewModel releasesModel = new ViewModelProvider(this).get(ReleasesViewModel.class); - releasesModel.getReleasesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + releasesModel.getReleasesList(instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List releasesListMain) { adapter = new ReleasesAdapter(getContext(), releasesListMain); diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java index 238d603a..7dd76b90 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java @@ -2,10 +2,8 @@ package org.mian.gitnex.fragments; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; -import android.text.Spanned; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -27,28 +25,12 @@ import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.ClickListener; +import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.UserRepositories; -import java.util.Collection; -import java.util.Collections; import java.util.Locale; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.core.CorePlugin; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.ext.tables.TablePlugin; -import io.noties.markwon.ext.tasklist.TaskListPlugin; -import io.noties.markwon.html.HtmlPlugin; -import io.noties.markwon.image.DefaultMediaDecoder; -import io.noties.markwon.image.ImageItem; -import io.noties.markwon.image.ImagesPlugin; -import io.noties.markwon.image.SchemeHandler; -import io.noties.markwon.image.gif.GifMediaDecoder; -import io.noties.markwon.image.svg.SvgMediaDecoder; -import io.noties.markwon.linkify.LinkifyPlugin; import retrofit2.Call; import retrofit2.Callback; @@ -113,10 +95,8 @@ public class RepoInfoFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_repo_info, container, false); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); + final String locale = tinyDb.getString("locale"); final String timeFormat = tinyDb.getString("dateFormat"); @@ -150,8 +130,8 @@ public class RepoInfoFragment extends Fragment { repoMetaFrame.setVisibility(View.GONE); - getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat); - getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename)); + getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, locale, timeFormat); + getFileContents(Authorization.get(getContext()), repoOwner, repoName, getResources().getString(R.string.defaultFilename)); if(isExpandViewVisible()) { toggleExpandView(); @@ -240,13 +220,12 @@ public class RepoInfoFragment extends Fragment { return repoMetaFrame.getVisibility() == View.VISIBLE; } - private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) { + private void getRepoInfo(String token, final String owner, String repo, final String locale, final String timeFormat) { - final TinyDB tinyDb = new TinyDB(getContext()); + final TinyDB tinyDb = TinyDB.getInstance(getContext()); Call call = RetrofitClient - .getInstance(instanceUrl, getContext()) - .getApiInterface() + .getApiInterface(ctx) .getUserRepository(token, owner, repo); call.enqueue(new Callback() { @@ -283,7 +262,7 @@ public class RepoInfoFragment extends Fragment { repoMetaForks.setText(repoInfo.getForks_count()); repoMetaWatchers.setText(repoInfo.getWatchers_count()); - repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) repoInfo.getSize())); + repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) (repoInfo.getSize() * 1024))); repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx)); if(timeFormat.equals("pretty")) { @@ -333,7 +312,7 @@ public class RepoInfoFragment extends Fragment { alertDialog.setTitle(getResources().getString(R.string.infoMoreInformation)); alertDialog.setView(view); - alertDialog.setNeutralButton(getResources().getString(R.string.close), null); + alertDialog.setPositiveButton(getString(R.string.okButton), null); alertDialog.create().show(); }); @@ -376,13 +355,10 @@ public class RepoInfoFragment extends Fragment { } - private void getFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) { - - final TinyDB tinyDb = new TinyDB(getContext()); + private void getFileContents(String token, final String owner, String repo, final String filename) { Call call = RetrofitClient - .getInstance(instanceUrl, getContext()) - .getApiInterface() + .getApiInterface(getContext()) .getFileContents(token, owner, repo, filename); call.enqueue(new Callback() { @@ -394,62 +370,7 @@ public class RepoInfoFragment extends Fragment { if (response.code() == 200) { - final Markwon markwon = Markwon.builder(requireContext()) - .usePlugin(CorePlugin.create()) - .usePlugin(ImagesPlugin.create(plugin -> { - plugin.addSchemeHandler(new SchemeHandler() { - @NonNull - @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = requireContext().getResources().getIdentifier( - raw.substring("drawable://".length()), - "drawable", - requireContext().getPackageName()); - - final Drawable drawable = requireContext().getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); - } - - @NonNull - @Override - public Collection supportedSchemes() { - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(requireContext().getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(requireContext().getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder - .codeTextColor(tinyDb.getInt("codeBlockColor")) - .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(getResources().getColor(R.color.lightBlue)); - } - }) - .usePlugin(TablePlugin.create(requireContext())) - .usePlugin(TaskListPlugin.create(requireContext())) - .usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create()) - .build(); - - Spanned bodyWithMD = null; - - if (response.body() != null) { - bodyWithMD = markwon.toMarkdown(response.body()); - } - - assert bodyWithMD != null; - markwon.setParsedMarkdown(repoFileContents, bodyWithMD); + new Markdown(ctx, response.body(), repoFileContents); } else if (response.code() == 401) { diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java index b6831bb4..38a9635d 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesByOrgFragment.java @@ -30,7 +30,6 @@ import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.viewmodels.RepositoriesByOrgViewModel; import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -74,11 +73,6 @@ public class RepositoriesByOrgFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_repositories_by_org, container, false); setHasOptionsMenu(true); - - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); noData = v.findViewById(R.id.noData); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); @@ -96,11 +90,11 @@ public class RepositoriesByOrgFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext(), pageSize, resultLimit); + RepositoriesByOrgViewModel.loadOrgRepos(Authorization.get(getContext()), orgName, getContext(), pageSize, resultLimit); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, pageSize, resultLimit); + fetchDataAsync(Authorization.get(getContext()), orgName, pageSize, resultLimit); return v; } @@ -109,23 +103,20 @@ public class RepositoriesByOrgFragment extends Fragment { public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); if(tinyDb.getBoolean("repoCreated")) { - RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext(), pageSize, resultLimit); + RepositoriesByOrgViewModel.loadOrgRepos(Authorization.get(getContext()), orgName, getContext(), pageSize, resultLimit); tinyDb.putBoolean("repoCreated", false); } } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, int pageSize, int resultLimit) { + private void fetchDataAsync(String instanceToken, String owner, int pageSize, int resultLimit) { RepositoriesByOrgViewModel orgRepoModel = new ViewModelProvider(this).get(RepositoriesByOrgViewModel.class); - orgRepoModel.getRepositoriesByOrg(instanceUrl, instanceToken, owner, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer>() { + orgRepoModel.getRepositoriesByOrg(instanceToken, owner, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List orgReposListMain) { adapter = new RepositoriesByOrgAdapter(getContext(), orgReposListMain); @@ -147,7 +138,7 @@ public class RepositoriesByOrgFragment extends Fragment { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); + boolean connToInternet = AppUtil.hasNetworkConnection(requireContext()); inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java index 79968b01..d33e5d1b 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java @@ -16,7 +16,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -25,14 +24,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import org.mian.gitnex.R; import org.mian.gitnex.activities.CreateRepoActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.ReposListAdapter; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.viewmodels.RepositoriesListViewModel; -import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -52,18 +48,13 @@ public class RepositoriesFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - final View v = inflater.inflate(R.layout.fragment_repositories, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navRepos)); + noDataRepo = v.findViewById(R.id.noData); mProgressBar = v.findViewById(R.id.progress_bar); mRecyclerView = v.findViewById(R.id.recyclerView); @@ -102,12 +93,11 @@ public class RepositoriesFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - RepositoriesListViewModel.loadReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit); + RepositoriesListViewModel.loadReposList(Authorization.get(getContext()), getContext(), pageSize, resultLimit); }, 50)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), pageSize, resultLimit); - + fetchDataAsync(Authorization.get(getContext()), pageSize, resultLimit); return v; } @@ -115,45 +105,41 @@ public class RepositoriesFragment extends Fragment { @Override public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); if(tinyDb.getBoolean("repoCreated")) { - RepositoriesListViewModel.loadReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit); + RepositoriesListViewModel.loadReposList(Authorization.get(getContext()), getContext(), pageSize, resultLimit); tinyDb.putBoolean("repoCreated", false); } } - private void fetchDataAsync(String instanceUrl, String instanceToken, int pageSize, int resultLimit) { + private void fetchDataAsync(String instanceToken, int pageSize, int resultLimit) { RepositoriesListViewModel repoModel = new ViewModelProvider(this).get(RepositoriesListViewModel.class); - repoModel.getUserRepositories(instanceUrl, instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List reposListMain) { - adapter = new ReposListAdapter(getContext(), reposListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noDataRepo.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noDataRepo.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); - } - }); + repoModel.getUserRepositories(instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), + reposListMain -> { + + adapter = new ReposListAdapter(getContext(), reposListMain); + if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); + noDataRepo.setVisibility(View.GONE); + } + else { + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noDataRepo.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); + }); } @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java index 5bb77e07..e31c977e 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/SearchIssuesFragment.java @@ -10,6 +10,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import org.mian.gitnex.adapters.SearchIssuesAdapter; import org.mian.gitnex.clients.RetrofitClient; @@ -38,10 +39,6 @@ public class SearchIssuesFragment extends Fragment { private SearchIssuesAdapter adapter; private List dataList; - private String instanceUrl; - private String loginUid; - private String instanceToken; - private int apiCallCurrentValue = 10; private int pageCurrentIndex = 1; private String type = "issues"; @@ -54,17 +51,15 @@ public class SearchIssuesFragment extends Fragment { setHasOptionsMenu(true); ctx = getContext(); - tinyDb = new TinyDB(getContext()); - - instanceUrl = tinyDb.getString("instanceUrl"); - loginUid = tinyDb.getString("loginUid"); - instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + tinyDb = TinyDB.getInstance(getContext()); dataList = new ArrayList<>(); adapter = new SearchIssuesAdapter(dataList, ctx); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(viewBinding.recyclerViewSearchIssues.getContext(), DividerItemDecoration.VERTICAL); + viewBinding.recyclerViewSearchIssues.addItemDecoration(dividerItemDecoration); viewBinding.recyclerViewSearchIssues.setHasFixedSize(true); viewBinding.recyclerViewSearchIssues.setLayoutManager(linearLayoutManager); viewBinding.recyclerViewSearchIssues.setAdapter(adapter); @@ -133,8 +128,8 @@ public class SearchIssuesFragment extends Fragment { viewBinding.loadingMoreView.setVisibility(View.VISIBLE); } - Call> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().queryIssues( - Authorization.returnAuthentication(getContext(), loginUid, instanceToken), searchKeyword, type, state, pageCurrentIndex); + Call> call = RetrofitClient.getApiInterface(getContext()) + .queryIssues(Authorization.get(getContext()), searchKeyword, type, state, pageCurrentIndex); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java index 93bc84f5..45f2f1fa 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java @@ -1,6 +1,7 @@ package org.mian.gitnex.fragments; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -12,13 +13,17 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import org.mian.gitnex.R; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.activities.SettingsAppearanceActivity; import org.mian.gitnex.activities.SettingsDraftsActivity; import org.mian.gitnex.activities.SettingsFileViewerActivity; +import org.mian.gitnex.activities.SettingsGeneralActivity; +import org.mian.gitnex.activities.SettingsNotificationsActivity; import org.mian.gitnex.activities.SettingsReportsActivity; import org.mian.gitnex.activities.SettingsSecurityActivity; import org.mian.gitnex.activities.SettingsTranslationActivity; import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Version; /** * Author M M Arif @@ -26,47 +31,66 @@ import org.mian.gitnex.helpers.TinyDB; public class SettingsFragment extends Fragment { + private Context ctx; + private TinyDB tinyDB; + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_settings, container, false); + ctx = getContext(); + tinyDB = TinyDB.getInstance(ctx); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navSettings)); + + LinearLayout generalFrame = v.findViewById(R.id.generalFrame); LinearLayout appearanceFrame = v.findViewById(R.id.appearanceFrame); LinearLayout fileViewerFrame = v.findViewById(R.id.fileViewerFrame); LinearLayout draftsFrame = v.findViewById(R.id.draftsFrame); LinearLayout securityFrame = v.findViewById(R.id.securityFrame); + LinearLayout notificationsFrame = v.findViewById(R.id.notificationsFrame); LinearLayout languagesFrame = v.findViewById(R.id.languagesFrame); LinearLayout reportsFrame = v.findViewById(R.id.reportsFrame); LinearLayout rateAppFrame = v.findViewById(R.id.rateAppFrame); LinearLayout aboutAppFrame = v.findViewById(R.id.aboutAppFrame); - appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsAppearanceActivity.class))); + if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) { - fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsFileViewerActivity.class))); + notificationsFrame.setVisibility(View.VISIBLE); + } - draftsFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsDraftsActivity.class))); + generalFrame.setOnClickListener(generalFrameCall -> startActivity(new Intent(ctx, SettingsGeneralActivity.class))); - securityFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsSecurityActivity.class))); + appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsAppearanceActivity.class))); - languagesFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsTranslationActivity.class))); + fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsFileViewerActivity.class))); - reportsFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsReportsActivity.class))); + draftsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsDraftsActivity.class))); + + securityFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsSecurityActivity.class))); + + notificationsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsNotificationsActivity.class))); + + languagesFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsTranslationActivity.class))); + + reportsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsReportsActivity.class))); rateAppFrame.setOnClickListener(aboutApp -> rateThisApp()); aboutAppFrame.setOnClickListener(aboutApp -> requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit()); return v; - } public void rateThisApp() { try { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + requireActivity().getPackageName()))); } catch(ActivityNotFoundException e) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + requireActivity().getPackageName()))); } } @@ -76,14 +100,12 @@ public class SettingsFragment extends Fragment { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); + if(tinyDB.getBoolean("refreshParent")) { - if(tinyDb.getBoolean("refreshParent")) { requireActivity().recreate(); requireActivity().overridePendingTransition(0, 0); - tinyDb.putBoolean("refreshParent", false); + tinyDB.putBoolean("refreshParent", false); } - } } diff --git a/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java index 1b537b0e..f6a98785 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java @@ -15,9 +15,7 @@ import android.view.inputmethod.EditorInfo; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; @@ -26,14 +24,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import org.mian.gitnex.R; import org.mian.gitnex.activities.CreateRepoActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.StarredReposListAdapter; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; -import org.mian.gitnex.models.UserRepositories; import org.mian.gitnex.viewmodels.StarredRepositoriesViewModel; -import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -79,16 +74,12 @@ public class StarredRepositoriesFragment extends Fragment { Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_starred_repositories, container, false); - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navStarredRepos)); + noData = v.findViewById(R.id.noData); mProgressBar = v.findViewById(R.id.progress_bar); mRecyclerView = v.findViewById(R.id.recyclerView); @@ -101,14 +92,10 @@ public class StarredRepositoriesFragment extends Fragment { createNewRepo = v.findViewById(R.id.addNewRepo); - createNewRepo.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View view) { - Intent intent = new Intent(view.getContext(), CreateRepoActivity.class); - startActivity(intent); - } + createNewRepo.setOnClickListener(view -> { + Intent intent = new Intent(view.getContext(), CreateRepoActivity.class); + startActivity(intent); }); mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -131,58 +118,54 @@ public class StarredRepositoriesFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit); + StarredRepositoriesViewModel.loadStarredReposList(Authorization.get(getContext()), getContext(), pageSize, resultLimit); }, 50)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), pageSize, resultLimit); + fetchDataAsync(Authorization.get(getContext()), pageSize, resultLimit); return v; } @Override public void onResume() { + super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); if(tinyDb.getBoolean("repoCreated")) { - StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), getContext(), pageSize, resultLimit); + StarredRepositoriesViewModel.loadStarredReposList(Authorization.get(getContext()), getContext(), pageSize, resultLimit); tinyDb.putBoolean("repoCreated", false); } - } - private void fetchDataAsync(String instanceUrl, String instanceToken, int pageSize, int resultLimit) { + private void fetchDataAsync(String instanceToken, int pageSize, int resultLimit) { StarredRepositoriesViewModel starredRepoModel = new ViewModelProvider(this).get(StarredRepositoriesViewModel.class); - starredRepoModel.getUserStarredRepositories(instanceUrl, instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List starredReposListMain) { - adapter = new StarredReposListAdapter(getContext(), starredReposListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noData.setVisibility(View.GONE); - } - else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noData.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); - } - }); + starredRepoModel.getUserStarredRepositories(instanceToken, getContext(), pageSize, resultLimit).observe(getViewLifecycleOwner(), + starredReposListMain -> { + + adapter = new StarredReposListAdapter(getContext(), starredReposListMain); + if(adapter.getItemCount() > 0) { + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.GONE); + } + else { + adapter.notifyDataSetChanged(); + mRecyclerView.setAdapter(adapter); + noData.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); + }); } @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java b/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java index 11f18570..31c55a5c 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/TeamsByOrgFragment.java @@ -24,13 +24,11 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; import org.mian.gitnex.adapters.TeamsByOrgAdapter; -import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.Teams; import org.mian.gitnex.viewmodels.TeamsByOrgViewModel; import java.util.List; -import java.util.Objects; /** * Author M M Arif @@ -73,10 +71,6 @@ public class TeamsByOrgFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_teams_by_org, container, false); setHasOptionsMenu(true); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); noDataTeams = v.findViewById(R.id.noDataTeams); final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); @@ -94,11 +88,11 @@ public class TeamsByOrgFragment extends Fragment { swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> { swipeRefresh.setRefreshing(false); - TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext()); + TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext()); }, 200)); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName); + fetchDataAsync(Authorization.get(getContext()), orgName); return v; } @@ -106,22 +100,19 @@ public class TeamsByOrgFragment extends Fragment { @Override public void onResume() { super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + TinyDB tinyDb = TinyDB.getInstance(getContext()); if(tinyDb.getBoolean("resumeTeams")) { - TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName, getContext()); + TeamsByOrgViewModel.loadTeamsByOrgList(Authorization.get(getContext()), orgName, getContext()); tinyDb.putBoolean("resumeTeams", false); } } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) { + private void fetchDataAsync(String instanceToken, String owner) { TeamsByOrgViewModel teamModel = new ViewModelProvider(this).get(TeamsByOrgViewModel.class); - teamModel.getTeamsByOrg(instanceUrl, instanceToken, owner, getContext()).observe(getViewLifecycleOwner(), new Observer>() { + teamModel.getTeamsByOrg(instanceToken, owner, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(@Nullable List orgTeamsListMain) { adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain); @@ -143,8 +134,6 @@ public class TeamsByOrgFragment extends Fragment { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); - inflater.inflate(R.menu.search_menu, menu); super.onCreateOptionsMenu(menu, inflater); diff --git a/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java index 64ddc5e2..17649660 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/UserAccountsFragment.java @@ -16,6 +16,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import org.mian.gitnex.R; import org.mian.gitnex.activities.AddNewAccountActivity; +import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.adapters.UserAccountsAdapter; import org.mian.gitnex.database.api.UserAccountsApi; import org.mian.gitnex.database.models.UserAccount; @@ -43,6 +44,8 @@ public class UserAccountsFragment extends Fragment { ctx = getContext(); setHasOptionsMenu(true); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.pageTitleUserAccounts)); + userAccountsList = new ArrayList<>(); userAccountsApi = new UserAccountsApi(ctx); diff --git a/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java b/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java index 4cee8e25..77a108e5 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java +++ b/app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java @@ -25,7 +25,7 @@ public class AlertDialogs { .setNeutralButton(copyNegativeButton, (dialog, which) -> dialog.dismiss()) .setPositiveButton(copyPositiveButton, (dialog, which) -> { - final TinyDB tinyDb = new TinyDB(context); + final TinyDB tinyDb = TinyDB.getInstance(context); tinyDb.putBoolean("loggedInMode", false); tinyDb.remove("basicAuthPassword"); tinyDb.putBoolean("basicAuthFlag", false); @@ -48,7 +48,7 @@ public class AlertDialogs { .setIcon(R.drawable.ic_info) .setPositiveButton(copyPositiveButton, (dialog, which) -> { - final TinyDB tinyDb = new TinyDB(context); + final TinyDB tinyDb = TinyDB.getInstance(context); tinyDb.putBoolean("loggedInMode", false); tinyDb.remove("basicAuthPassword"); tinyDb.putBoolean("basicAuthFlag", false); @@ -62,7 +62,7 @@ public class AlertDialogs { alertDialogBuilder.create().show(); } - public static void labelDeleteDialog(final Context context, final String labelTitle, final String labelId, String title, String message, String positiveButton, String negativeButton) { + public static void labelDeleteDialog(final Context context, final String labelTitle, final String labelId, String title, String message, String positiveButton, String negativeButton, String type, String orgName) { new AlertDialog.Builder(context) .setTitle(title + labelTitle) @@ -73,6 +73,8 @@ public class AlertDialogs { Intent intent = new Intent(context, CreateLabelActivity.class); intent.putExtra("labelId", labelId); intent.putExtra("labelAction", "delete"); + intent.putExtra("type", type); + intent.putExtra("orgName", orgName); context.startActivity(intent); }) diff --git a/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java b/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java index bd175b31..6b3e7d5c 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java +++ b/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java @@ -5,11 +5,12 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.util.Base64; import android.util.DisplayMetrics; +import android.util.TypedValue; import android.view.View; +import androidx.annotation.ColorInt; +import androidx.core.content.pm.PackageInfoCompat; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -32,32 +33,14 @@ public class AppUtil { public static boolean hasNetworkConnection(Context context) { - boolean haveConnectedWifi = false; - boolean haveConnectedMobile = false; - - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - assert cm != null; - NetworkInfo[] netInfo = cm.getAllNetworkInfo(); - for(NetworkInfo ni : netInfo) { - if(ni.getTypeName().equalsIgnoreCase("WIFI")) { - if(ni.isConnected()) { - haveConnectedWifi = true; - } - } - if(ni.getTypeName().equalsIgnoreCase("MOBILE")) { - if(ni.isConnected()) { - haveConnectedMobile = true; - } - } - } - return haveConnectedWifi || haveConnectedMobile; + return NetworkStatusObserver.get(context).hasNetworkConnection(); } public static int getAppBuildNo(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); - return packageInfo.versionCode; + return (int) PackageInfoCompat.getLongVersionCode(packageInfo); } catch(PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get package name: " + e); @@ -124,13 +107,23 @@ public class AppUtil { public static String getTimestampFromDate(Context context, Date date) { - TinyDB tinyDB = new TinyDB(context); + TinyDB tinyDB = TinyDB.getInstance(context); Locale locale = new Locale(tinyDB.getString("locale")); return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", locale).format(date); } + @ColorInt + public static int getColorFromAttribute(Context context, int resid) { + + TypedValue typedValue = new TypedValue(); + context.getTheme().resolveAttribute(resid, typedValue, true); + + return typedValue.data; + + } + public static String customDateFormat(String customDate) { String[] parts = customDate.split("-"); diff --git a/app/src/main/java/org/mian/gitnex/helpers/Authorization.java b/app/src/main/java/org/mian/gitnex/helpers/Authorization.java index 19d7a5d3..6a520d65 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/Authorization.java +++ b/app/src/main/java/org/mian/gitnex/helpers/Authorization.java @@ -9,33 +9,18 @@ import okhttp3.Credentials; public class Authorization { - public static String returnAuthentication(Context context, String loginUid, String token) { + public static String get(Context context) { - TinyDB tinyDb = new TinyDB(context); + TinyDB tinyDb = TinyDB.getInstance(context); + String loginUid = tinyDb.getString("loginUid"); - String credential; + if(tinyDb.getBoolean("basicAuthFlag") && + !tinyDb.getString("basicAuthPassword").isEmpty()) { - if(tinyDb.getBoolean("basicAuthFlag")) { + return Credentials.basic(loginUid, tinyDb.getString("basicAuthPassword")); + } - if (!tinyDb.getString("basicAuthPassword").isEmpty()) { - - credential = Credentials.basic(loginUid, tinyDb.getString("basicAuthPassword")); - - } - else { - - credential = token; - - } - } - else { - - credential = token; - - } - - return credential; - - } + return "token " + tinyDb.getString(loginUid + "-token"); + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/ChangeLog.java b/app/src/main/java/org/mian/gitnex/helpers/ChangeLog.java index 6d0f4d9e..bfe5a4cf 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/ChangeLog.java +++ b/app/src/main/java/org/mian/gitnex/helpers/ChangeLog.java @@ -1,10 +1,5 @@ package org.mian.gitnex.helpers; -import java.io.IOException; -import java.util.Objects; -import org.mian.gitnex.R; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; import android.app.Activity; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -12,6 +7,11 @@ import android.content.res.XmlResourceParser; import android.text.Html; import android.util.Log; import androidx.appcompat.app.AlertDialog; +import org.mian.gitnex.R; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import java.io.IOException; +import java.util.Objects; /** * Author M M Arif @@ -90,13 +90,14 @@ public class ChangeLog { String changelogMessage = getChangelog(resId, res); - androidx.appcompat.app.AlertDialog.Builder builder = new AlertDialog.Builder(changelogActivity); + AlertDialog.Builder builder = new AlertDialog.Builder(changelogActivity); + builder.setTitle(R.string.changelogTitle); builder.setMessage(Html.fromHtml("" + changelogMessage + "")); builder.setNeutralButton(R.string.close, null); builder.setCancelable(false); - builder.create(); - builder.show(); + + builder.create().show(); } diff --git a/app/src/main/java/org/mian/gitnex/helpers/Markdown.java b/app/src/main/java/org/mian/gitnex/helpers/Markdown.java new file mode 100644 index 00000000..093f3aa5 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/Markdown.java @@ -0,0 +1,90 @@ +package org.mian.gitnex.helpers; + +import android.content.Context; +import android.graphics.Typeface; +import android.text.Spanned; +import android.widget.TextView; +import androidx.annotation.NonNull; +import org.mian.gitnex.R; +import org.mian.gitnex.clients.PicassoService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.core.CorePlugin; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.ext.tables.TablePlugin; +import io.noties.markwon.ext.tasklist.TaskListPlugin; +import io.noties.markwon.html.HtmlPlugin; +import io.noties.markwon.image.picasso.PicassoImagesPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.syntax.Prism4jTheme; +import io.noties.markwon.syntax.Prism4jThemeDarkula; +import io.noties.markwon.syntax.Prism4jThemeDefault; +import io.noties.markwon.syntax.SyntaxHighlightPlugin; +import io.noties.prism4j.Prism4j; +import io.noties.prism4j.annotations.PrismBundle; + +/** + * @author opyale + */ + +@PrismBundle( + includeAll = true, + grammarLocatorClassName = ".CustomGrammarLocator" +) +public class Markdown { + + private static final ExecutorService executorService = Executors.newCachedThreadPool(); + + private final Context context; + private final String markdown; + private final TextView textView; + + public Markdown(@NonNull Context context, @NonNull String markdown, @NonNull TextView textView) { + + this.context = context; + this.markdown = markdown; + this.textView = textView; + + executorService.execute(new Renderer()); + + } + + private class Renderer implements Runnable { + + @Override + public void run() { + + Prism4jTheme prism4jTheme = TinyDB.getInstance(context).getString("currentTheme").equals("dark") ? + Prism4jThemeDarkula.create() : + Prism4jThemeDefault.create(); + + Markwon.Builder builder = Markwon.builder(context) + .usePlugin(CorePlugin.create()) + .usePlugin(HtmlPlugin.create()) + .usePlugin(LinkifyPlugin.create()) + .usePlugin(TablePlugin.create(context)) + .usePlugin(TaskListPlugin.create(context)) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(PicassoImagesPlugin.create(PicassoService.getInstance(context).get())) + .usePlugin(SyntaxHighlightPlugin.create(new Prism4j(new CustomGrammarLocator()), prism4jTheme)) + .usePlugin(new AbstractMarkwonPlugin() { + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.codeBlockTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf")); + builder.codeTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf")); + builder.linkColor(context.getResources().getColor(R.color.lightBlue)); + } + }); + + Markwon markwon = builder.build(); + Spanned spanned = markwon.toMarkdown(markdown); + + textView.post(() -> markwon.setParsedMarkdown(textView, spanned)); + + } + } +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java b/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java deleted file mode 100644 index 6d557f20..00000000 --- a/app/src/main/java/org/mian/gitnex/helpers/NetworkObserver.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.mian.gitnex.helpers; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import androidx.appcompat.app.AppCompatActivity; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; - -/** - * Author M M Arif - */ - -public class NetworkObserver implements LifecycleObserver { - - private ConnectivityManager mConnectivityMgr; - private Context mContext; - private NetworkStateReceiver mNetworkStateReceiver; - - public interface ConnectionStateListener { - void onAvailable(boolean isAvailable); - } - - public NetworkObserver(Context context) { - mContext = context; - mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - ((AppCompatActivity) mContext).getLifecycle().addObserver(this); - } - - - public void onInternetStateListener(ConnectionStateListener listener) { - - mNetworkStateReceiver = new NetworkStateReceiver(listener); - IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(mNetworkStateReceiver, intentFilter); - - } - - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - public void onDestroy() { - - ((AppCompatActivity) mContext).getLifecycle().removeObserver(this); - - if (mNetworkStateReceiver != null) { - mContext.unregisterReceiver(mNetworkStateReceiver); - } - - } - - - public class NetworkStateReceiver extends BroadcastReceiver { - - ConnectionStateListener mListener; - - public NetworkStateReceiver(ConnectionStateListener listener) { - mListener = listener; - } - - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getExtras() != null) { - NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo(); - - if (activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) { - - mListener.onAvailable(true); // connected - - } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) { - - mListener.onAvailable(false); // disconnected - - } - } - } - } - -} diff --git a/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java b/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java new file mode 100644 index 00000000..5845be53 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/NetworkStatusObserver.java @@ -0,0 +1,109 @@ +package org.mian.gitnex.helpers; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import androidx.annotation.NonNull; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author opyale + */ +public class NetworkStatusObserver { + + private static NetworkStatusObserver networkStatusObserver; + + private final AtomicBoolean hasNetworkConnection = new AtomicBoolean(false); + private final List networkStatusListeners = new ArrayList<>(); + + private final Object mutex = new Object(); + private boolean hasInitialized = false; + + private NetworkStatusObserver(Context context) { + + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkRequest networkRequest = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + .build(); + + cm.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() { + + @Override + public void onAvailable(@NonNull Network network) { + hasNetworkConnection.set(true); + networkStatusChanged(); + checkInitialized(); + } + + @Override + public void onLost(@NonNull Network network) { + hasNetworkConnection.set(false); + networkStatusChanged(); + checkInitialized(); + } + + private void checkInitialized() { + + if(!hasInitialized) { + hasInitialized = true; + synchronized(mutex) { + mutex.notify(); + } + } + } + + }); + + synchronized(mutex) { + try { + // This is actually not the recommended way to do this, but there + // is no other option besides upgrading to API level 26 + // in order to use the built-in timeout functionality of {@code requestNetwork()} + // which in turn gives us access to {@code onUnavailable()} . + mutex.wait(5); + } catch(InterruptedException ignored) {} + } + + if(!hasInitialized) { + hasInitialized = true; + } + } + + private void networkStatusChanged() { + boolean hasNetworkConnection = hasNetworkConnection(); + + for(NetworkStatusListener networkStatusListener : networkStatusListeners) { + networkStatusListener.onNetworkStatusChanged(hasNetworkConnection); + } + } + + public boolean hasNetworkConnection() { + return hasNetworkConnection.get(); + } + + public void registerNetworkStatusListener(NetworkStatusListener networkStatusListener) { + networkStatusListeners.add(networkStatusListener); + networkStatusListener.onNetworkStatusChanged(hasNetworkConnection()); + } + + public void unregisterNetworkStatusListener(NetworkStatusListener networkStatusListener) { + networkStatusListeners.remove(networkStatusListener); + } + + public interface NetworkStatusListener { void onNetworkStatusChanged(boolean hasNetworkConnection); } + + public static NetworkStatusObserver get(Context context) { + if(networkStatusObserver == null) { + networkStatusObserver = new NetworkStatusObserver(context); + } + + return networkStatusObserver; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java b/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java index a931f930..96143358 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java +++ b/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java @@ -30,12 +30,12 @@ public class PicassoCache implements Cache { private static final String CACHE_MAP_FILE = "cacheMap"; - private File cachePath; - private HashMap cacheMap; + private final File cachePath; + private final HashMap cacheMap; public PicassoCache(File cachePath, Context ctx) throws IOException, ClassNotFoundException { - TinyDB tinyDb = new TinyDB(ctx); + TinyDB tinyDb = TinyDB.getInstance(ctx); CACHE_SIZE = FilesData.returnOnlyNumber(tinyDb.getString("cacheSizeImagesStr")) * 1024 * 1024; this.cachePath = cachePath; @@ -45,9 +45,7 @@ public class PicassoCache implements Cache { if(cacheMapExists(cachePath)) { cacheMap.putAll(loadCacheMap()); - } - } @Override diff --git a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java index 1ba029a3..2af5e693 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java +++ b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java @@ -15,7 +15,7 @@ public abstract class StaticGlobalVariables { public static int getCurrentResultLimit(Context context) { - Version version = new Version(new TinyDB(context).getString("giteaVersion")); + Version version = new Version(TinyDB.getInstance(context).getString("giteaVersion")); return version.higherOrEqual("1.12") ? resultLimitNewGiteaInstances : resultLimitOldGiteaInstances; } @@ -25,11 +25,11 @@ public abstract class StaticGlobalVariables { public static String tagPullRequestsList = "PullRequestsListFragment"; public static String tagIssuesList = "IssuesListFragment"; public static String tagMilestonesAdapter = "MilestonesAdapter"; - public static String draftsRepository = "DraftsRepository"; - public static String repositoriesRepository = "RepositoriesRepository"; + public static String draftsApi = "DraftsApi"; + public static String repositoriesApi = "RepositoriesApi"; public static String replyToIssueActivity = "ReplyToIssueActivity"; public static String tagDraftsBottomSheet = "BottomSheetDraftsFragment"; - public static String userAccountsRepository = "UserAccountsRepository"; + public static String userAccountsApi = "UserAccountsApi"; // issues variables public static int issuesPageInit = 1; @@ -43,6 +43,11 @@ public abstract class StaticGlobalVariables { // drafts public static String draftTypeComment = "comment"; - public static String draftTypeIssue = "issue"; + public static String draftTypeIssue = "Issue"; + public static String draftTypePull = "Pull"; + // polling - notifications + public static int minimumPollingDelay = 1; + public static int defaultPollingDelay = 15; + public static int maximumPollingDelay = 720; } diff --git a/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java b/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java index fd75f04e..d4e782a8 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java +++ b/app/src/main/java/org/mian/gitnex/helpers/TinyDB.java @@ -6,7 +6,6 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.os.Environment; -import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import java.io.File; @@ -18,14 +17,23 @@ import java.util.Map; public class TinyDB { - private SharedPreferences preferences; + private static TinyDB tinyDB; + + private final SharedPreferences preferences; private String DEFAULT_APP_IMAGEDATA_DIRECTORY; private String lastImagePath = ""; - public TinyDB(Context appContext) { - preferences = PreferenceManager.getDefaultSharedPreferences(appContext); + private TinyDB(Context appContext) { + preferences = appContext.getSharedPreferences(appContext.getPackageName() + "_preferences", Context.MODE_PRIVATE); } + public static synchronized TinyDB getInstance(Context context) { + if(tinyDB == null) { + tinyDB = new TinyDB(context); + } + + return tinyDB; + } /** * Decodes the Bitmap from 'path' and returns it diff --git a/app/src/main/java/org/mian/gitnex/helpers/UserMentions.java b/app/src/main/java/org/mian/gitnex/helpers/UserMentions.java index 9b94411c..a2297f3f 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/UserMentions.java +++ b/app/src/main/java/org/mian/gitnex/helpers/UserMentions.java @@ -14,7 +14,7 @@ import java.util.regex.Pattern; public class UserMentions { - public static Spannable UserMentionsFunc(Context mCtx, CharSequence bodyWithMD, String currentItemBody) { + public static Spannable UserMentionsFunc(Context mCtx, CharSequence bodyWithMD) { Spannable bodyWithMentions = new SpannableString(bodyWithMD); Pattern pattern = Pattern.compile("@\\w+"); diff --git a/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java b/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java index f7fbf9a7..2d06e043 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java +++ b/app/src/main/java/org/mian/gitnex/helpers/ssl/MemorizingTrustManager.java @@ -56,7 +56,7 @@ public class MemorizingTrustManager implements X509TrustManager { private Handler masterHandler; private SharedPreferences keyStoreStorage; private KeyStore appKeyStore; - private X509TrustManager defaultTrustManager; + private final X509TrustManager defaultTrustManager; private X509TrustManager appTrustManager; /** @@ -634,7 +634,7 @@ public class MemorizingTrustManager implements X509TrustManager { class MemorizingHostnameVerifier implements HostnameVerifier { - private HostnameVerifier defaultVerifier; + private final HostnameVerifier defaultVerifier; MemorizingHostnameVerifier(HostnameVerifier wrapped) { 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 df0f2fd4..c8cf41ef 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -1,13 +1,16 @@ package org.mian.gitnex.interfaces; import com.google.gson.JsonElement; +import org.mian.gitnex.models.APISettings; import org.mian.gitnex.models.AddEmail; +import org.mian.gitnex.models.AttachmentSettings; import org.mian.gitnex.models.Branches; import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.Commits; import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.CreateLabel; import org.mian.gitnex.models.CreatePullRequest; +import org.mian.gitnex.models.CreateStatusOption; import org.mian.gitnex.models.DeleteFile; import org.mian.gitnex.models.EditFile; import org.mian.gitnex.models.Emails; @@ -15,8 +18,10 @@ import org.mian.gitnex.models.ExploreRepositories; import org.mian.gitnex.models.Files; import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.IssueComments; +import org.mian.gitnex.models.IssueReaction; import org.mian.gitnex.models.Issues; import org.mian.gitnex.models.Labels; +import org.mian.gitnex.models.MarkdownOption; import org.mian.gitnex.models.MergePullRequest; import org.mian.gitnex.models.Milestones; import org.mian.gitnex.models.NewFile; @@ -28,10 +33,14 @@ import org.mian.gitnex.models.OrganizationRepository; import org.mian.gitnex.models.Permission; import org.mian.gitnex.models.PullRequests; import org.mian.gitnex.models.Releases; +import org.mian.gitnex.models.RepositorySettings; import org.mian.gitnex.models.RepositoryTransfer; +import org.mian.gitnex.models.Status; import org.mian.gitnex.models.Teams; +import org.mian.gitnex.models.UISettings; import org.mian.gitnex.models.UpdateIssueAssignees; import org.mian.gitnex.models.UpdateIssueState; +import org.mian.gitnex.models.UserHeatmap; import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.models.UserOrganizations; import org.mian.gitnex.models.UserRepositories; @@ -58,6 +67,9 @@ import retrofit2.http.Query; public interface ApiInterface { + @GET("version") // gitea version API without any auth + Call getGiteaVersion(); + @GET("version") // gitea version API Call getGiteaVersionWithBasic(@Header("Authorization") String authorization); @@ -67,8 +79,26 @@ public interface ApiInterface { @GET("version") // gitea version API Call getGiteaVersionWithToken(@Header("Authorization") String token); - @GET("user") // username, full name, email - Call getUserInfo(@Header("Authorization") String token); + @POST("markdown") + Call renderMarkdown(@Header("Authorization") String token, @Body MarkdownOption markdownOption); + + @POST("markdown/raw") + Call renderRawMarkdown(@Header("Authorization") String token, @Body String body); + + @GET("signing-key.gpg") // Get default signing-key.gpg + Call getSigningKey(@Header("Authorization") String token); + + @GET("settings/api") // Get instance's global settings for api + Call getAPISettings(@Header("Authorization") String token); + + @GET("settings/attachment") // Get instance's global settings for attachments + Call getAttachmentSettings(@Header("Authorization") String token); + + @GET("settings/repository") // Get instance's global settings for repositories + Call getRepositorySettings(@Header("Authorization") String token); + + @GET("settings/ui") // Get instance's global settings for ui + Call getUISettings(@Header("Authorization") String token); @GET("users/{username}/tokens") // get user token Call> getUserTokens(@Header("Authorization") String authorization, @Path("username") String loginUid); @@ -109,6 +139,9 @@ public interface ApiInterface { @PUT("repos/{owner}/{repo}/notifications") // Mark notification threads as read, pinned or unread on a specific repo Call markRepoNotificationThreadsAsRead(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("all") Boolean all, @Query("status-types") String[] statusTypes, @Query("to-status") String toStatus, @Query("last_read_at") String last_read_at); + @GET("user") // username, full name, email + Call getUserInfo(@Header("Authorization") String token); + @GET("user/orgs") // get user organizations Call> getUserOrgs(@Header("Authorization") String token); @@ -127,6 +160,24 @@ public interface ApiInterface { @POST("user/repos") // create new repository Call createNewUserRepository(@Header("Authorization") String token, @Body OrganizationRepository jsonStr); + @GET("user/followers") // get user followers + Call> getFollowers(@Header("Authorization") String token); + + @GET("user/following") // get following + Call> getFollowing(@Header("Authorization") String token); + + @POST("user/emails") // add new email + Call addNewEmail(@Header("Authorization") String token, @Body AddEmail jsonStr); + + @GET("user/emails") // get user emails + Call> getUserEmails(@Header("Authorization") String token); + + @GET("user/starred") // get user starred repositories + Call> getUserStarredRepos(@Header("Authorization") String token, @Query("page") int page, @Query("limit") int limit); + + @GET("users/{username}/heatmap") // Get a user's heatmap + Call> getUserHeatmap(@Header("Authorization") String token, @Path("username") String username); + @GET("repos/{owner}/{repo}") // get repo information Call getUserRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); @@ -173,7 +224,19 @@ public interface ApiInterface { Call createNewIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body CreateIssue jsonStr); @GET("repos/{owner}/{repo}/labels") // get labels list - Call> getlabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); + Call> getLabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); + + @GET("orgs/{owner}/labels") // get org labels list + Call> getOrganizationLabels(@Header("Authorization") String token, @Path("owner") String ownerName); + + @POST("orgs/{owner}/labels") // create org label + Call createOrganizationLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Body CreateLabel jsonStr); + + @PATCH("orgs/{owner}/labels/{id}") // update / patch org label + Call patchOrganizationLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("id") int labelID, @Body CreateLabel jsonStr); + + @DELETE("orgs/{owner}/labels/{id}") // delete org label + Call deleteOrganizationLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("id") int labelID); @GET("users/{username}/repos") // get current logged in user repositories Call> getCurrentUserRepositories(@Header("Authorization") String token, @Path("username") String username, @Query("page") int page, @Query("limit") int limit); @@ -187,9 +250,6 @@ public interface ApiInterface { @PATCH("repos/{owner}/{repo}/labels/{index}") // update / patch a label Call patchLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int labelIndex, @Body CreateLabel jsonStr); - @GET("user/starred") // get user starred repositories - Call> getUserStarredRepos(@Header("Authorization") String token, @Query("page") int page, @Query("limit") int limit); - @GET("orgs/{orgName}/repos") // get repositories by org Call> getReposByOrg(@Header("Authorization") String token, @Path("orgName") String orgName, @Query("page") int page, @Query("limit") int limit); @@ -220,17 +280,23 @@ public interface ApiInterface { @PATCH("repos/{owner}/{repo}/issues/comments/{commentId}") // edit a comment Call patchIssueComment(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("commentId") int commentId, @Body IssueComments jsonStr); - @GET("user/followers") // get user followers - Call> getFollowers(@Header("Authorization") String token); + @GET("repos/{owner}/{repo}/issues/comments/{commentId}/reactions") // get comment reactions + Call> getIssueCommentReactions(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("commentId") int commentId); - @GET("user/following") // get following - Call> getFollowing(@Header("Authorization") String token); + @POST("repos/{owner}/{repo}/issues/comments/{commentId}/reactions") // add reaction to a comment + Call setIssueCommentReaction(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("commentId") int commentId, @Body IssueReaction jsonStr); - @POST("user/emails") // add new email - Call addNewEmail(@Header("Authorization") String token, @Body AddEmail jsonStr); + @HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/comments/{commentId}/reactions", hasBody = true) // delete a reaction of a comment + Call removeIssueCommentReaction(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("commentId") int commentId, @Body IssueReaction jsonStr); - @GET("user/emails") // get user emails - Call> getUserEmails(@Header("Authorization") String token); + @GET("repos/{owner}/{repo}/issues/{index}/reactions") // get issue reactions + Call> getIssueReactions(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex); + + @POST("repos/{owner}/{repo}/issues/{index}/reactions") // add reaction to an issue + Call setIssueReaction(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body IssueReaction jsonStr); + + @HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/{index}/reactions", hasBody = true) // delete a reaction of an issue + Call removeIssueReaction(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body IssueReaction jsonStr); @GET("repos/{owner}/{repo}/issues/{index}/labels") // get issue labels Call> getIssueLabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex); @@ -331,6 +397,9 @@ public interface ApiInterface { @POST("repos/{owner}/{repo}/pulls") // create a pull request Call createPullRequest(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body CreatePullRequest jsonStr); + @GET("repos/{owner}/{repo}/pulls/{index}") // get pull request by index + Call getPullRequestByIndex(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Path("index") int index); + @GET("repos/{owner}/{repo}/commits") // get all commits Call> getRepositoryCommits(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("sha") String branchName, @Query("limit") int limit); @@ -354,4 +423,12 @@ public interface ApiInterface { @GET("repos/{owner}/{repo}/forks") // get all repo forks Call> getRepositoryForks(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Query("page") int page, @Query("limit") int limit); + + @POST("repos/{owner}/{repo}/statuses/{sha}") // Create a commit status + Call createCommitStatus(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Path("sha") String sha, @Body CreateStatusOption createStatusOption); + + @GET("repos/{owner}/{repo}/statuses/{sha}") // Get a commit's statuses + Call> getCommitStatuses(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("sort") String sort, @Query("state") String state, @Query("page") int page, @Query("limit") int limit); + + } diff --git a/app/src/main/java/org/mian/gitnex/models/APISettings.java b/app/src/main/java/org/mian/gitnex/models/APISettings.java new file mode 100644 index 00000000..ff633aea --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/APISettings.java @@ -0,0 +1,34 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class APISettings { + + private int default_git_trees_per_page; + private int default_max_blob_size; + private int default_paging_num; + private int max_response_items; + + public int getDefault_git_trees_per_page() { + + return default_git_trees_per_page; + } + + public int getDefault_max_blob_size() { + + return default_max_blob_size; + } + + public int getDefault_paging_num() { + + return default_paging_num; + } + + public int getMax_response_items() { + + return max_response_items; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/AttachmentSettings.java b/app/src/main/java/org/mian/gitnex/models/AttachmentSettings.java new file mode 100644 index 00000000..0f2dcef0 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/AttachmentSettings.java @@ -0,0 +1,34 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class AttachmentSettings { + + private String allowed_types; + private boolean enabled; + private float max_files; + private float max_size; + + public String getAllowed_types() { + + return allowed_types; + } + + public boolean isEnabled() { + + return enabled; + } + + public float getMax_files() { + + return max_files; + } + + public float getMax_size() { + + return max_size; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/CreateStatusOption.java b/app/src/main/java/org/mian/gitnex/models/CreateStatusOption.java new file mode 100644 index 00000000..74cdc8d8 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/CreateStatusOption.java @@ -0,0 +1,36 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class CreateStatusOption { + + private String context; + private String description; + private String statusState; + private String target_url; + + public CreateStatusOption(String context, String description, String statusState, String target_url) { + this.context = context; + this.description = description; + this.statusState = statusState; + this.target_url = target_url; + } + + public String getContext() { + return context; + } + + public String getDescription() { + return description; + } + + public String getStatusState() { + return statusState; + } + + public String getTarget_url() { + return target_url; + } +} diff --git a/app/src/main/java/org/mian/gitnex/models/IssueReaction.java b/app/src/main/java/org/mian/gitnex/models/IssueReaction.java new file mode 100644 index 00000000..74fcc838 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/IssueReaction.java @@ -0,0 +1,71 @@ +package org.mian.gitnex.models; + +import java.util.Date; + +/** + * Author 6543 + */ + +public class IssueReaction { + + private String content; + private userObject user; + private Date created_at; + + public IssueReaction(String content) { + this.content = content; + } + + public static class userObject { + + private int id; + private String login; + private String full_name; + private String email; + private String avatar_url; + private String language; + private String username; + + public int getId() { + return id; + } + + public String getLogin() { + return login; + } + + public String getFull_name() { + return full_name; + } + + public String getEmail() { + return email; + } + + public String getAvatar_url() { + return avatar_url; + } + + public String getLanguage() { + return language; + } + + public String getUsername() { + return username; + } + + } + + public String getContent() { + return content; + } + + public userObject getUser() { + return user; + } + + public Date getCreated_at() { + return created_at; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/MarkdownOption.java b/app/src/main/java/org/mian/gitnex/models/MarkdownOption.java new file mode 100644 index 00000000..444dea44 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/MarkdownOption.java @@ -0,0 +1,42 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class MarkdownOption { + + private String Context; + private String Mode; + private String Text; + private boolean Wiki; + + public MarkdownOption(String context, String mode, String text, boolean wiki) { + + Context = context; + Mode = mode; + Text = text; + Wiki = wiki; + } + + public String getContext() { + + return Context; + } + + public String getMode() { + + return Mode; + } + + public String getText() { + + return Text; + } + + public boolean isWiki() { + + return Wiki; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/MultiSelectModel.java b/app/src/main/java/org/mian/gitnex/models/MultiSelectModel.java deleted file mode 100644 index 710a8b35..00000000 --- a/app/src/main/java/org/mian/gitnex/models/MultiSelectModel.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mian.gitnex.models; - -/** - * Author com.github.abumoallim, modified by M M Arif - */ - -public class MultiSelectModel { - - private Integer id; - private String name; - private Boolean isSelected; - - public MultiSelectModel(Integer id, String name) { - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Boolean getSelected() { - return isSelected; - } - - public void setSelected(Boolean selected) { - isSelected = selected; - } - -} diff --git a/app/src/main/java/org/mian/gitnex/models/RepositorySettings.java b/app/src/main/java/org/mian/gitnex/models/RepositorySettings.java new file mode 100644 index 00000000..0fdf189f --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/RepositorySettings.java @@ -0,0 +1,22 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class RepositorySettings { + + private boolean http_git_disabled; + private boolean mirrors_disabled; + + public boolean isHttp_git_disabled() { + + return http_git_disabled; + } + + public boolean isMirrors_disabled() { + + return mirrors_disabled; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/Status.java b/app/src/main/java/org/mian/gitnex/models/Status.java new file mode 100644 index 00000000..a0012d11 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/Status.java @@ -0,0 +1,56 @@ +package org.mian.gitnex.models; + +import java.util.Date; + +/** + * Author opyale + */ + +public class Status { + + private String context; + private Date created_at; + private UserInfo creator; + private String description; + private int id; + private String status; + private String target_url; + private Date updated_at; + private String url; + + public String getContext() { + return context; + } + + public Date getCreated_at() { + return created_at; + } + + public UserInfo getCreator() { + return creator; + } + + public String getDescription() { + return description; + } + + public int getId() { + return id; + } + + public String getStatus() { + return status; + } + + public String getTarget_url() { + return target_url; + } + + public Date getUpdated_at() { + return updated_at; + } + + public String getUrl() { + return url; + } +} diff --git a/app/src/main/java/org/mian/gitnex/models/UISettings.java b/app/src/main/java/org/mian/gitnex/models/UISettings.java new file mode 100644 index 00000000..67b6e7ba --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/UISettings.java @@ -0,0 +1,16 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class UISettings { + + private String[] allowed_reactions; + + public String[] getAllowed_reactions() { + + return allowed_reactions; + } + +} diff --git a/app/src/main/java/org/mian/gitnex/models/UserHeatmap.java b/app/src/main/java/org/mian/gitnex/models/UserHeatmap.java new file mode 100644 index 00000000..f0a62c3b --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/models/UserHeatmap.java @@ -0,0 +1,12 @@ +package org.mian.gitnex.models; + +/** + * Author opyale + */ + +public class UserHeatmap { + + private long contributions; + private long timestamp; + +} diff --git a/app/src/main/java/org/mian/gitnex/notifications/NotificationsMaster.java b/app/src/main/java/org/mian/gitnex/notifications/NotificationsMaster.java index 8449f75c..aca4981e 100644 --- a/app/src/main/java/org/mian/gitnex/notifications/NotificationsMaster.java +++ b/app/src/main/java/org/mian/gitnex/notifications/NotificationsMaster.java @@ -7,6 +7,7 @@ import androidx.work.ExistingPeriodicWorkPolicy; import androidx.work.NetworkType; import androidx.work.PeriodicWorkRequest; import androidx.work.WorkManager; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Version; import java.util.concurrent.TimeUnit; @@ -36,32 +37,35 @@ public class NotificationsMaster { public static void hireWorker(Context context) { - TinyDB tinyDB = new TinyDB(context); + TinyDB tinyDB = TinyDB.getInstance(context); - if(notificationsSupported == -1) { - checkVersion(tinyDB); - } + if(tinyDB.getBoolean("notificationsEnabled", true)) { - if(notificationsSupported == 1) { + if(notificationsSupported == -1) checkVersion(tinyDB); - Constraints.Builder constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .setRequiresBatteryNotLow(false) - .setRequiresStorageNotLow(false) - .setRequiresCharging(false); + if(notificationsSupported == 1) { - if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Constraints.Builder constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .setRequiresBatteryNotLow(false) + .setRequiresStorageNotLow(false) + .setRequiresCharging(false); + + if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + + constraints.setRequiresDeviceIdle(false); + } + + int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay), 15); + + PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, pollingDelayMinutes, TimeUnit.MINUTES) + .setConstraints(constraints.build()) + .addTag(context.getPackageName()) + .build(); + + WorkManager.getInstance(context).enqueueUniquePeriodicWork(context.getPackageName(), ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest); - constraints.setRequiresDeviceIdle(false); } - - PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, tinyDB.getInt("pollingDelayMinutes"), TimeUnit.MINUTES) - .setConstraints(constraints.build()) - .addTag(context.getPackageName()) - .build(); - - WorkManager.getInstance(context).enqueueUniquePeriodicWork(context.getPackageName(), ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest); - } } } diff --git a/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java b/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java index c92284ba..b7e13062 100644 --- a/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java +++ b/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java @@ -1,5 +1,6 @@ package org.mian.gitnex.notifications; +import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; @@ -11,12 +12,14 @@ import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; import androidx.work.Worker; import androidx.work.WorkerParameters; import org.mian.gitnex.R; import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.models.NotificationThread; import java.util.Date; @@ -41,18 +44,16 @@ public class NotificationsWorker extends Worker { super(context, workerParams); this.context = context; - this.tinyDB = new TinyDB(context); - + this.tinyDB = TinyDB.getInstance(context); } @NonNull @Override public Result doWork() { - String instanceUrl = tinyDB.getString("instanceUrl"); String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token"); - int notificationLoops = tinyDB.getInt("pollingDelayMinutes") >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10); + int notificationLoops = tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay) >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10); for(int i=0; i> call = RetrofitClient.getInstance(instanceUrl, context) - .getApiInterface() + Call> call = RetrofitClient + .getApiInterface(context) .getNotificationThreads(token, false, new String[]{"unread"}, previousRefreshTimestamp, null, 1, MAXIMUM_NOTIFICATIONS); @@ -74,23 +75,20 @@ public class NotificationsWorker extends Worker { assert response.body() != null; List notificationThreads = response.body(); - Log.i("ReceivedNotifications", String.valueOf(notificationThreads.size())); if(!notificationThreads.isEmpty()) { - for(NotificationThread notificationThread : notificationThreads) { - - sendNotification(notificationThread); - } + sendNotification(notificationThreads); } tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date())); - - } else { + } + else { Log.e("onError", String.valueOf(response.code())); } - } catch(Exception e) { + } + catch(Exception e) { Log.e("onError", e.toString()); } @@ -101,60 +99,125 @@ public class NotificationsWorker extends Worker { Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime)); } - } catch (InterruptedException ignored) {} + } + catch (InterruptedException ignored) {} } return Result.success(); - } - private void sendNotification(NotificationThread notificationThread) { + private void sendNotification(List notificationThreads) { + + int summaryId = 0; + PendingIntent pendingIntent = getPendingIntent(); + + NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context); + attachNotificationChannel(notificationManagerCompat); + + Notification summaryNotification = new NotificationCompat.Builder(context, context.getPackageName()) + .setContentTitle(context.getString(R.string.newMessages)) + .setContentText(String.format(context.getString(R.string.youHaveGotNewNotifications), notificationThreads.size())) + .setSmallIcon(R.drawable.gitnex_transparent) + .setGroup(context.getPackageName()) + .setGroupSummary(true) + .setAutoCancel(true) + .setContentIntent(pendingIntent) + .build(); + + notificationManagerCompat.notify(summaryId, summaryNotification); + + for(NotificationThread notificationThread : notificationThreads) { + + NotificationManagerCompat notificationManagerCompat1 = NotificationManagerCompat.from(context); + attachNotificationChannel(notificationManagerCompat1); + + String subjectUrl = notificationThread.getSubject().getUrl(); + String issueId = context.getResources().getString(R.string.hash) + subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1); + String notificationHeader = issueId + " " + notificationThread.getSubject().getTitle() + " " + String.format(context.getResources().getString(R.string.notificationExtraInfo), notificationThread.getRepository().getFull_name(), notificationThread.getSubject().getType()); + + NotificationCompat.Builder builder1 = getBaseNotificationBuilder() + .setContentTitle(notificationHeader) + .setGroup(context.getPackageName()) + .setContentIntent(pendingIntent); + + pushNotification(notificationManagerCompat1, builder1.build()); + } + } + + private void pushNotification(NotificationManagerCompat notificationManagerCompat, Notification notification) { + + int previousNotificationId = tinyDB.getInt("previousNotificationId", 0); + int nextPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1; + + tinyDB.putInt("previousNotificationId", nextPreviousNotificationId); + notificationManagerCompat.notify(previousNotificationId, notification); + } + + private void attachNotificationChannel(NotificationManagerCompat notificationManagerCompat) { + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + + NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name), + NotificationManager.IMPORTANCE_DEFAULT); + + notificationChannel.setDescription(context.getString(R.string.notificationChannelDescription)); + + if(tinyDB.getBoolean("notificationsEnableVibration", true)) { + + notificationChannel.setVibrationPattern(VIBRATION_PATTERN); + notificationChannel.enableVibration(true); + } + else { + + notificationChannel.enableVibration(false); + } + + if(tinyDB.getBoolean("notificationsEnableLights", true)) { + + notificationChannel.setLightColor(tinyDB.getInt("notificationsLightColor", Color.GREEN)); + notificationChannel.enableLights(true); + } + else { + + notificationChannel.enableLights(false); + } + + notificationManagerCompat.createNotificationChannel(notificationChannel); + } + } + + private NotificationCompat.Builder getBaseNotificationBuilder() { + + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, context.getPackageName()) + .setSmallIcon(R.drawable.gitnex_transparent) + .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) + .setCategory(NotificationCompat.CATEGORY_MESSAGE) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setAutoCancel(true); + + if(tinyDB.getBoolean("notificationsEnableLights", true)) { + + builder.setLights(tinyDB.getInt("notificationsLightColor", Color.GREEN), 1500, 1500); + } + + if(tinyDB.getBoolean("notificationsEnableVibration", true)) { + + builder.setVibrate(VIBRATION_PATTERN); + } + else { + + builder.setVibrate(null); + } + + return builder; + } + + private PendingIntent getPendingIntent() { Intent intent = new Intent(context, MainActivity.class); intent.putExtra("launchFragment", "notifications"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - - if(notificationManager != null) { - - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - - NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name), - NotificationManager.IMPORTANCE_HIGH); - - notificationChannel.enableLights(true); - notificationChannel.setLightColor(Color.GREEN); - notificationChannel.enableVibration(true); - notificationChannel.setVibrationPattern(VIBRATION_PATTERN); - - notificationManager.createNotificationChannel(notificationChannel); - - } - - String subjectUrl = notificationThread.getSubject().getUrl(); - String issueId = context.getResources().getString(R.string.hash) + subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1); - - String notificationHeader = issueId + " " + notificationThread.getSubject().getTitle(); - String notificationBody = String.format(context.getResources().getString(R.string.notificationBody), - notificationThread.getSubject().getType()); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, context.getPackageName()) - .setSmallIcon(R.drawable.gitnex_transparent).setContentTitle(notificationHeader) - .setContentText(notificationBody) - .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .setContentIntent(pendingIntent).setVibrate(VIBRATION_PATTERN).setAutoCancel(true); - - int previousNotificationId = tinyDB.getInt("previousNotificationId", 0); - int newPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1; - - tinyDB.putInt("previousNotificationId", newPreviousNotificationId); - - notificationManager.notify(previousNotificationId, builder.build()); - - } + return PendingIntent.getActivity(context, 0, intent, 0); } - } diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/AdminGetUsersViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/AdminGetUsersViewModel.java index 112b3402..4d834265 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/AdminGetUsersViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/AdminGetUsersViewModel.java @@ -24,19 +24,18 @@ public class AdminGetUsersViewModel extends ViewModel { private static MutableLiveData> usersList; - public LiveData> getUsersList(Context ctx, String instanceUrl, String token) { + public LiveData> getUsersList(Context ctx, String token) { usersList = new MutableLiveData<>(); - loadUsersList(ctx, instanceUrl, token); + loadUsersList(ctx, token); return usersList; } - public static void loadUsersList(final Context ctx, String instanceUrl, String token) { + public static void loadUsersList(final Context ctx, String token) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .adminGetUsers(token); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java index e46018b4..26d55d00 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/BranchesViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Branches; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Branches; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class BranchesViewModel extends ViewModel { private static MutableLiveData> branchesList; - public LiveData> getBranchesList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public LiveData> getBranchesList(String token, String owner, String repo, Context ctx) { branchesList = new MutableLiveData<>(); - loadBranchesList(instanceUrl, token, owner, repo, ctx); + loadBranchesList(token, owner, repo, ctx); return branchesList; } - public static void loadBranchesList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public static void loadBranchesList(String token, String owner, String repo, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getBranches(token, owner, repo); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/CollaboratorsViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/CollaboratorsViewModel.java index 5233c4ad..a54d81ee 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/CollaboratorsViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/CollaboratorsViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Collaborators; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Collaborators; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class CollaboratorsViewModel extends ViewModel { private static MutableLiveData> collaboratorsList; - public LiveData> getCollaboratorsList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public LiveData> getCollaboratorsList(String token, String owner, String repo, Context ctx) { collaboratorsList = new MutableLiveData<>(); - loadCollaboratorsListList(instanceUrl, token, owner, repo, ctx); + loadCollaboratorsListList(token, owner, repo, ctx); return collaboratorsList; } - private static void loadCollaboratorsListList(String instanceUrl, String token, String owner, String repo, Context ctx) { + private static void loadCollaboratorsListList(String token, String owner, String repo, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getCollaborators(token, owner, repo); call.enqueue(new Callback>() { 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 70db17bb..15116a3e 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java @@ -27,19 +27,18 @@ 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, ProgressBar progressBar, TextView noDataFiles) { + public LiveData> getFilesList(String token, String owner, String repo, String ref, Context ctx, ProgressBar progressBar, TextView noDataFiles) { filesList = new MutableLiveData<>(); - loadFilesList(instanceUrl, token, owner, repo, ref, ctx, progressBar, noDataFiles); + loadFilesList(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, ProgressBar progressBar, TextView noDataFiles) { + private static void loadFilesList(String token, String owner, String repo, String ref, final Context ctx, ProgressBar progressBar, TextView noDataFiles) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getFiles(token, owner, repo, ref); call.enqueue(new Callback>() { @@ -79,19 +78,18 @@ public class FilesViewModel extends ViewModel { }); } - public LiveData> getFilesList2(String instanceUrl, String token, String owner, String repo, String filesDir, String ref, Context ctx, ProgressBar progressBar, TextView noDataFiles) { + public LiveData> getFilesList2(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, progressBar, noDataFiles); + loadFilesList2(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, ProgressBar progressBar, TextView noDataFiles) { + private static void loadFilesList2(String token, String owner, String repo, String filesDir, String ref, final Context ctx, ProgressBar progressBar, TextView noDataFiles) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getDirFiles(token, owner, repo, filesDir, ref); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/IssueCommentsViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/IssueCommentsViewModel.java index 24f3be81..a9d473d9 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/IssueCommentsViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/IssueCommentsViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.IssueComments; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.IssueComments; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class IssueCommentsViewModel extends ViewModel { private static MutableLiveData> issueComments; - public LiveData> getIssueCommentList(String instanceUrl, String token, String owner, String repo, int index, Context ctx) { + public LiveData> getIssueCommentList(String token, String owner, String repo, int index, Context ctx) { issueComments = new MutableLiveData<>(); - loadIssueComments(instanceUrl, token, owner, repo, index, ctx); + loadIssueComments(token, owner, repo, index, ctx); return issueComments; } - public static void loadIssueComments(String instanceUrl, String token, String owner, String repo, int index, Context ctx) { + public static void loadIssueComments(String token, String owner, String repo, int index, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getIssueComments(token, owner, repo, index); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/LabelsViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/LabelsViewModel.java index 7d650ec8..c83c4df5 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/LabelsViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/LabelsViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Labels; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Labels; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,20 +21,19 @@ public class LabelsViewModel extends ViewModel { private static MutableLiveData> labelsList; - public LiveData> getLabelsList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public LiveData> getLabelsList(String token, String owner, String repo, Context ctx) { labelsList = new MutableLiveData<>(); - loadLabelsList(instanceUrl, token, owner, repo, ctx); + loadLabelsList(token, owner, repo, ctx); return labelsList; } - public static void loadLabelsList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public static void loadLabelsList(String token, String owner, String repo, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getlabels(token, owner, repo); + .getApiInterface(ctx) + .getLabels(token, owner, repo); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/MembersByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/MembersByOrgViewModel.java index d7afbb0d..3a1480b9 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/MembersByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/MembersByOrgViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserInfo; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserInfo; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class MembersByOrgViewModel extends ViewModel { private static MutableLiveData> membersList; - public LiveData> getMembersList(String instanceUrl, String token, String owner, Context ctx) { + public LiveData> getMembersList(String token, String owner, Context ctx) { membersList = new MutableLiveData<>(); - loadMembersList(instanceUrl, token, owner, ctx); + loadMembersList(token, owner, ctx); return membersList; } - private static void loadMembersList(String instanceUrl, String token, String owner, Context ctx) { + private static void loadMembersList(String token, String owner, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getMembersByOrg(token, owner); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/MyRepositoriesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/MyRepositoriesViewModel.java index 3e36b521..15a82907 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/MyRepositoriesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/MyRepositoriesViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserRepositories; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserRepositories; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,21 +21,20 @@ public class MyRepositoriesViewModel extends ViewModel { private static MutableLiveData> myReposList; - public LiveData> getCurrentUserRepositories(String instanceUrl, String token, String username, Context ctx, int page, int limit) { + public LiveData> getCurrentUserRepositories(String token, String username, Context ctx, int page, int limit) { //if (myReposList == null) { myReposList = new MutableLiveData<>(); - loadMyReposList(instanceUrl, token, username, ctx, page, limit); + loadMyReposList(token, username, ctx, page, limit); //} return myReposList; } - public static void loadMyReposList(String instanceUrl, String token, String username, Context ctx, int page, int limit) { + public static void loadMyReposList(String token, String username, Context ctx, int page, int limit) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getCurrentUserRepositories(token, username, page, limit); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationLabelsViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationLabelsViewModel.java new file mode 100644 index 00000000..1340b08c --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationLabelsViewModel.java @@ -0,0 +1,67 @@ +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; +import androidx.lifecycle.ViewModel; +import org.jetbrains.annotations.NotNull; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Labels; +import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Author M M Arif + */ + +public class OrganizationLabelsViewModel extends ViewModel { + + private static MutableLiveData> orgLabelsList; + + public LiveData> getOrgLabelsList(String token, String owner, Context ctx, ProgressBar progressBar, TextView noData) { + + orgLabelsList = new MutableLiveData<>(); + loadOrgLabelsList(token, owner, ctx, progressBar, noData); + + return orgLabelsList; + } + + public static void loadOrgLabelsList(String token, String owner, Context ctx, ProgressBar progressBar, TextView noData) { + + Call> call = RetrofitClient + .getApiInterface(ctx) + .getOrganizationLabels(token, owner); + + call.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + + if(response.isSuccessful()) { + + orgLabelsList.postValue(response.body()); + } + else { + + progressBar.setVisibility(View.GONE); + noData.setVisibility(View.VISIBLE); + Log.i("onResponse-org-labels", String.valueOf(response.code())); + } + } + + @Override + public void onFailure(@NonNull Call> call, @NotNull Throwable t) { + Log.i("onFailure", t.toString()); + } + + }); + + } +} diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java index 9cd5a461..a40517cb 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserOrganizations; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserOrganizations; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,21 +21,20 @@ public class OrganizationListViewModel extends ViewModel { private static MutableLiveData> orgsList; - public LiveData> getUserOrgs(String instanceUrl, String token, Context ctx) { + public LiveData> getUserOrgs(String token, Context ctx) { //if (orgsList == null) { orgsList = new MutableLiveData<>(); - loadOrgsList(instanceUrl, token, ctx); + loadOrgsList(token, ctx); //} return orgsList; } - public static void loadOrgsList(String instanceUrl, String token, Context ctx) { + public static void loadOrgsList(String token, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getUserOrgs(token); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileEmailsViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileEmailsViewModel.java index ea3bfa5f..28da6ec8 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileEmailsViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileEmailsViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Emails; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Emails; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class ProfileEmailsViewModel extends ViewModel { private static MutableLiveData> emailsList; - public LiveData> getEmailsList(String instanceUrl, String token, Context ctx) { + public LiveData> getEmailsList(String token, Context ctx) { emailsList = new MutableLiveData<>(); - loadEmailsList(instanceUrl, token, ctx); + loadEmailsList(token, ctx); return emailsList; } - public static void loadEmailsList(String instanceUrl, String token, Context ctx) { + public static void loadEmailsList(String token, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getUserEmails(token); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java index e6f2c6a4..4ddcd249 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserInfo; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserInfo; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class ProfileFollowersViewModel extends ViewModel { private static MutableLiveData> followersList; - public LiveData> getFollowersList(String instanceUrl, String token, Context ctx) { + public LiveData> getFollowersList(String token, Context ctx) { followersList = new MutableLiveData<>(); - loadFollowersList(instanceUrl, token, ctx); + loadFollowersList(token, ctx); return followersList; } - public static void loadFollowersList(String instanceUrl, String token, Context ctx) { + public static void loadFollowersList(String token, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getFollowers(token); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java index 4ca1551f..2d974b7b 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserInfo; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserInfo; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class ProfileFollowingViewModel extends ViewModel { private static MutableLiveData> followingList; - public LiveData> getFollowingList(String instanceUrl, String token, Context ctx) { + public LiveData> getFollowingList(String token, Context ctx) { followingList = new MutableLiveData<>(); - loadFollowingList(instanceUrl, token, ctx); + loadFollowingList(token, ctx); return followingList; } - public static void loadFollowingList(String instanceUrl, String token, Context ctx) { + public static void loadFollowingList(String token, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getFollowing(token); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ReleasesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ReleasesViewModel.java index 9a988823..ec686395 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/ReleasesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/ReleasesViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Releases; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Releases; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class ReleasesViewModel extends ViewModel { private static MutableLiveData> releasesList; - public LiveData> getReleasesList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public LiveData> getReleasesList(String token, String owner, String repo, Context ctx) { releasesList = new MutableLiveData<>(); - loadReleasesList(instanceUrl, token, owner, repo, ctx); + loadReleasesList(token, owner, repo, ctx); return releasesList; } - public static void loadReleasesList(String instanceUrl, String token, String owner, String repo, Context ctx) { + public static void loadReleasesList(String token, String owner, String repo, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getReleases(token, owner, repo); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/RepoStargazersViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/RepoStargazersViewModel.java index 57f98f13..af8f4470 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/RepoStargazersViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/RepoStargazersViewModel.java @@ -21,19 +21,18 @@ public class RepoStargazersViewModel extends ViewModel { private static MutableLiveData> stargazersList; - public LiveData> getRepoStargazers(String instanceUrl, String token, String repoOwner, String repoName, Context ctx) { + public LiveData> getRepoStargazers(String token, String repoOwner, String repoName, Context ctx) { stargazersList = new MutableLiveData<>(); - loadRepoStargazers(instanceUrl, token, repoOwner, repoName, ctx); + loadRepoStargazers(token, repoOwner, repoName, ctx); return stargazersList; } - private static void loadRepoStargazers(String instanceUrl, String token, String repoOwner, String repoName, Context ctx) { + private static void loadRepoStargazers(String token, String repoOwner, String repoName, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getRepoStargazers(token, repoOwner, repoName); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/RepoWatchersViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/RepoWatchersViewModel.java index c298b3a3..3755a00e 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/RepoWatchersViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/RepoWatchersViewModel.java @@ -21,19 +21,18 @@ public class RepoWatchersViewModel extends ViewModel { private static MutableLiveData> watchersList; - public LiveData> getRepoWatchers(String instanceUrl, String token, String repoOwner, String repoName, Context ctx) { + public LiveData> getRepoWatchers(String token, String repoOwner, String repoName, Context ctx) { watchersList = new MutableLiveData<>(); - loadRepoWatchers(instanceUrl, token, repoOwner, repoName, ctx); + loadRepoWatchers(token, repoOwner, repoName, ctx); return watchersList; } - private static void loadRepoWatchers(String instanceUrl, String token, String repoOwner, String repoName, Context ctx) { + private static void loadRepoWatchers(String token, String repoOwner, String repoName, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getRepoWatchers(token, repoOwner, repoName); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesByOrgViewModel.java index 913e35f5..df97855c 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesByOrgViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserRepositories; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserRepositories; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class RepositoriesByOrgViewModel extends ViewModel { private static MutableLiveData> orgReposList; - public LiveData> getRepositoriesByOrg(String instanceUrl, String token, String orgName, Context ctx, int page, int limit) { + public LiveData> getRepositoriesByOrg(String token, String orgName, Context ctx, int page, int limit) { orgReposList = new MutableLiveData<>(); - loadOrgRepos(instanceUrl, token, orgName, ctx, page, limit); + loadOrgRepos(token, orgName, ctx, page, limit); return orgReposList; } - public static void loadOrgRepos(String instanceUrl, String token, String orgName, Context ctx, int page, int limit) { + public static void loadOrgRepos(String token, String orgName, Context ctx, int page, int limit) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getReposByOrg(token, orgName, page, limit); call.enqueue(new Callback>() { @@ -59,4 +58,4 @@ public class RepositoriesByOrgViewModel extends ViewModel { } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesListViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesListViewModel.java index ebdd93ff..e4975a24 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesListViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/RepositoriesListViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserRepositories; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserRepositories; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,21 +21,20 @@ public class RepositoriesListViewModel extends ViewModel { private static MutableLiveData> reposList; - public LiveData> getUserRepositories(String instanceUrl, String token, Context ctx, int page, int limit) { + public LiveData> getUserRepositories(String token, Context ctx, int page, int limit) { //if (reposList == null) { reposList = new MutableLiveData<>(); - loadReposList(instanceUrl, token, ctx, page, limit); + loadReposList(token, ctx, page, limit); //} return reposList; } - public static void loadReposList(String instanceUrl, String token, Context ctx, int page, int limit) { + public static void loadReposList(String token, Context ctx, int page, int limit) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getUserRepositories(token, page, limit); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/StarredRepositoriesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/StarredRepositoriesViewModel.java index f1826030..55dada7e 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/StarredRepositoriesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/StarredRepositoriesViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserRepositories; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserRepositories; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class StarredRepositoriesViewModel extends ViewModel { private static MutableLiveData> reposList; - public LiveData> getUserStarredRepositories(String instanceUrl, String token, Context ctx, int page, int limit) { + public LiveData> getUserStarredRepositories(String token, Context ctx, int page, int limit) { reposList = new MutableLiveData<>(); - loadStarredReposList(instanceUrl, token, ctx, page, limit); + loadStarredReposList(token, ctx, page, limit); return reposList; } - public static void loadStarredReposList(String instanceUrl, String token, Context ctx, int page, int limit) { + public static void loadStarredReposList(String token, Context ctx, int page, int limit) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getUserStarredRepos(token, page, limit); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java index 2bc4837e..4a029bf5 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/TeamMembersByOrgViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.UserInfo; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.UserInfo; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class TeamMembersByOrgViewModel extends ViewModel { private static MutableLiveData> teamMembersList; - public LiveData> getMembersByOrgList(String instanceUrl, String token, int teamId, Context ctx) { + public LiveData> getMembersByOrgList(String token, int teamId, Context ctx) { teamMembersList = new MutableLiveData<>(); - loadMembersByOrgList(instanceUrl, token, teamId, ctx); + loadMembersByOrgList(token, teamId, ctx); return teamMembersList; } - private static void loadMembersByOrgList(String instanceUrl, String token, int teamId, Context ctx) { + private static void loadMembersByOrgList(String token, int teamId, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getTeamMembersByOrg(token, teamId); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java index a2b9b286..af872c6c 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/TeamsByOrgViewModel.java @@ -2,13 +2,13 @@ package org.mian.gitnex.viewmodels; import android.content.Context; import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Teams; -import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.models.Teams; +import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -21,19 +21,18 @@ public class TeamsByOrgViewModel extends ViewModel { private static MutableLiveData> teamsList; - public LiveData> getTeamsByOrg(String instanceUrl, String token, String orgName, Context ctx) { + public LiveData> getTeamsByOrg(String token, String orgName, Context ctx) { teamsList = new MutableLiveData<>(); - loadTeamsByOrgList(instanceUrl, token, orgName, ctx); + loadTeamsByOrgList(token, orgName, ctx); return teamsList; } - public static void loadTeamsByOrgList(String instanceUrl, String token, String orgName, Context ctx) { + public static void loadTeamsByOrgList(String token, String orgName, Context ctx) { Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() + .getApiInterface(ctx) .getTeamsByOrg(token, orgName); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/helpers/DiffTextView.java b/app/src/main/java/org/mian/gitnex/views/DiffTextView.java similarity index 97% rename from app/src/main/java/org/mian/gitnex/helpers/DiffTextView.java rename to app/src/main/java/org/mian/gitnex/views/DiffTextView.java index dcb81e7a..2e9503c3 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/DiffTextView.java +++ b/app/src/main/java/org/mian/gitnex/views/DiffTextView.java @@ -1,4 +1,4 @@ -package org.mian.gitnex.helpers; +package org.mian.gitnex.views; import android.content.Context; import android.util.AttributeSet; diff --git a/app/src/main/java/org/mian/gitnex/views/ReactionList.java b/app/src/main/java/org/mian/gitnex/views/ReactionList.java new file mode 100644 index 00000000..e651e51e --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/views/ReactionList.java @@ -0,0 +1,149 @@ +package org.mian.gitnex.views; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.TextView; +import androidx.cardview.widget.CardView; +import com.vdurmont.emoji.Emoji; +import com.vdurmont.emoji.EmojiManager; +import org.mian.gitnex.R; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.models.IssueReaction; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import retrofit2.Response; + +/** + * @author opyale + */ + +@SuppressLint("ViewConstructor") +public class ReactionList extends HorizontalScrollView { + + private enum ReactionType { COMMENT, ISSUE } + private OnReactionAddedListener onReactionAddedListener; + + @SuppressLint("SetTextI18n") + public ReactionList(Context context, Bundle bundle) { + + super(context); + + LinearLayout root = new LinearLayout(context); + + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + + root.setOrientation(LinearLayout.HORIZONTAL); + root.setGravity(Gravity.START); + root.setLayoutParams(layoutParams); + + addView(root); + setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + TinyDB tinyDB = TinyDB.getInstance(context); + + String loginUid = tinyDB.getString("loginUid"); + String repoOwner = bundle.getString("repoOwner"); + String repoName = bundle.getString("repoName"); + + int id; + ReactionType reactionType; + + if(bundle.containsKey("commentId")) { + id = bundle.getInt("commentId"); + reactionType = ReactionType.COMMENT; + } else { + id = bundle.getInt("issueId"); + reactionType = ReactionType.ISSUE; + } + + new Thread(() -> { + + try { + + Response> response = null; + + switch(reactionType) { + + case ISSUE: + response = RetrofitClient + .getApiInterface(context) + .getIssueReactions(Authorization.get(context), repoOwner, repoName, id) + .execute(); + break; + + case COMMENT: + response = RetrofitClient + .getApiInterface(context) + .getIssueCommentReactions(Authorization.get(context), repoOwner, repoName, id) + .execute(); + break; + + } + + Map> sortedReactions = new HashMap<>(); + + if(response.isSuccessful() && response.body() != null) { + + for(IssueReaction issueReaction : response.body()) { + + if(sortedReactions.containsKey(issueReaction.getContent())) { + + sortedReactions.get(issueReaction.getContent()).add(issueReaction); + } else { + List issueReactions = new ArrayList<>(); + issueReactions.add(issueReaction); + + sortedReactions.put(issueReaction.getContent(), issueReactions); + } + } + } + + for(String content : sortedReactions.keySet()) { + + List issueReactions = sortedReactions.get(content); + + @SuppressLint("InflateParams") CardView reactionBadge = (CardView) LayoutInflater.from(context) + .inflate(R.layout.layout_reaction_badge, this, false); + + for(IssueReaction issueReaction : issueReactions) { + + if(issueReaction.getUser().getLogin().equals(loginUid)) { + reactionBadge.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor)); + break; + } + } + + Emoji emoji = EmojiManager.getForAlias(content); + + ((TextView) reactionBadge.findViewById(R.id.symbol)).setText(((emoji == null) ? content : emoji.getUnicode()) + " " + issueReactions.size()); + + root.post(() -> root.addView(reactionBadge)); + onReactionAddedListener.reactionAdded(); + + } + + } catch (IOException ignored) {} + + }).start(); + + } + + public void setOnReactionAddedListener(OnReactionAddedListener onReactionAddedListener) { + this.onReactionAddedListener = onReactionAddedListener; + } + + public interface OnReactionAddedListener { void reactionAdded(); } + +} diff --git a/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java b/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java new file mode 100644 index 00000000..32da4d05 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java @@ -0,0 +1,238 @@ +package org.mian.gitnex.views; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.TextView; +import androidx.cardview.widget.CardView; +import com.vdurmont.emoji.Emoji; +import com.vdurmont.emoji.EmojiManager; +import org.mian.gitnex.R; +import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.models.IssueReaction; +import org.mian.gitnex.models.UISettings; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import retrofit2.Response; + +/** + * @author opyale + */ + +@SuppressLint("ViewConstructor") +public class ReactionSpinner extends HorizontalScrollView { + + private enum ReactionType { COMMENT, ISSUE } + private enum ReactionAction { REMOVE, ADD } + + private OnInteractedListener onInteractedListener; + + public ReactionSpinner(Context context, Bundle bundle) { + + super(context); + + LinearLayout root = new LinearLayout(context); + + int dens = AppUtil.getPixelsFromDensity(context, 10); + + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + + root.setOrientation(LinearLayout.HORIZONTAL); + root.setPadding(dens, 0, dens, 0); + root.setGravity(Gravity.START); + root.setLayoutParams(layoutParams); + + TinyDB tinyDB = TinyDB.getInstance(context); + + String loginUid = tinyDB.getString("loginUid"); + String repoOwner = bundle.getString("repoOwner"); + String repoName = bundle.getString("repoName"); + + int id; + ReactionType reactionType; + + if(bundle.containsKey("commentId")) { + id = bundle.getInt("commentId"); + reactionType = ReactionType.COMMENT; + } else { + id = bundle.getInt("issueId"); + reactionType = ReactionType.ISSUE; + } + + new Thread(() -> { + + try { + + List allReactions = getReactions(repoOwner, repoName, reactionType, id); + + for(String allowedReaction : getAllowedReactions()) { + + @SuppressLint("InflateParams") CardView reactionButton = (CardView) LayoutInflater.from(context) + .inflate(R.layout.layout_reaction_button, root, false); + + IssueReaction myReaction = null; + + for(IssueReaction issueReaction : allReactions) { + + if(issueReaction.getContent().equals(allowedReaction) && issueReaction.getUser().getLogin().equals(loginUid)) { + myReaction = issueReaction; + break; + } + } + + ReactionAction reactionAction; + + if(myReaction != null) { + + reactionButton.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor)); + reactionAction = ReactionAction.REMOVE; + } else { + reactionAction = ReactionAction.ADD; + } + + reactionButton.setOnClickListener(v -> new Thread(() -> { + + try { + if(react(repoOwner, repoName, reactionType, reactionAction, new IssueReaction(allowedReaction), id)) { + v.post(() -> onInteractedListener.onInteracted()); + } + } catch(IOException ignored) {} + + }).start()); + + Emoji emoji = EmojiManager.getForAlias(allowedReaction); + + ((TextView) reactionButton.findViewById(R.id.symbol)).setText((emoji == null) ? allowedReaction : emoji.getUnicode()); + root.post(() -> root.addView(reactionButton)); + + } + + } catch(IOException ignored) {} + + }).start(); + + setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + addView(root); + + } + + private boolean react(String repoOwner, String repoName, ReactionType reactionType, ReactionAction reactionAction, IssueReaction issueReaction, int id) throws IOException { + + Response response = null; + + switch(reactionType) { + + case ISSUE: + switch(reactionAction) { + + case ADD: + response = RetrofitClient + .getApiInterface(getContext()) + .setIssueReaction(Authorization.get(getContext()), repoOwner, repoName, id, issueReaction) + .execute(); + break; + + + case REMOVE: + response = RetrofitClient + .getApiInterface(getContext()) + .removeIssueReaction(Authorization.get(getContext()), repoOwner, repoName, id, issueReaction) + .execute(); + break; + + } + break; + + case COMMENT: + switch(reactionAction) { + + case ADD: + response = RetrofitClient + .getApiInterface(getContext()) + .setIssueCommentReaction(Authorization.get(getContext()), repoOwner, repoName, id, issueReaction) + .execute(); + break; + + + case REMOVE: + response = RetrofitClient + .getApiInterface(getContext()) + .removeIssueCommentReaction(Authorization.get(getContext()), repoOwner, repoName, id, issueReaction) + .execute(); + break; + + } + break; + + } + + return response.isSuccessful(); + + } + + private List getReactions(String repoOwner, String repoName, ReactionType reactionType, int id) throws IOException { + + Response> response = null; + + switch(reactionType) { + + case ISSUE: + response = RetrofitClient + .getApiInterface(getContext()) + .getIssueReactions(Authorization.get(getContext()), repoOwner, repoName, id) + .execute(); + break; + + case COMMENT: + response = RetrofitClient + .getApiInterface(getContext()) + .getIssueCommentReactions(Authorization.get(getContext()), repoOwner, repoName, id) + .execute(); + break; + + } + + if(response.isSuccessful() && response.body() != null) + return response.body(); + else + return Collections.emptyList(); + + } + + private List getAllowedReactions() throws IOException { + + List allowedReactions = new ArrayList<>(); + + Response response = RetrofitClient + .getApiInterface(getContext()) + .getUISettings(Authorization.get(getContext())) + .execute(); + + if(response.isSuccessful() && response.body() != null) { + allowedReactions.addAll(Arrays.asList(response.body().getAllowed_reactions())); + } else { + allowedReactions.addAll(Arrays.asList("+1", "-1", "laugh", "hooray", "confused", "heart", "rocket", "eyes")); + } + + return allowedReactions; + + } + + public void setOnInteractedListener(OnInteractedListener onInteractedListener) { + this.onInteractedListener = onInteractedListener; + } + + public interface OnInteractedListener { void onInteracted(); } + +} diff --git a/app/src/main/res/drawable-hdpi/gitnex_transparent.png b/app/src/main/res/drawable-hdpi/gitnex_transparent.png index 4303b106..f56e14dd 100644 Binary files a/app/src/main/res/drawable-hdpi/gitnex_transparent.png and b/app/src/main/res/drawable-hdpi/gitnex_transparent.png differ diff --git a/app/src/main/res/drawable-xhdpi/gitnex_transparent.png b/app/src/main/res/drawable-xhdpi/gitnex_transparent.png index b87e5dc9..7faac349 100644 Binary files a/app/src/main/res/drawable-xhdpi/gitnex_transparent.png and b/app/src/main/res/drawable-xhdpi/gitnex_transparent.png differ diff --git a/app/src/main/res/drawable-xxhdpi/gitnex_transparent.png b/app/src/main/res/drawable-xxhdpi/gitnex_transparent.png index b787f9c9..047c2dcf 100644 Binary files a/app/src/main/res/drawable-xxhdpi/gitnex_transparent.png and b/app/src/main/res/drawable-xxhdpi/gitnex_transparent.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/gitnex_transparent.png b/app/src/main/res/drawable-xxxhdpi/gitnex_transparent.png index bbb2a36b..c8414564 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/gitnex_transparent.png and b/app/src/main/res/drawable-xxxhdpi/gitnex_transparent.png differ diff --git a/app/src/main/res/drawable/ic_save.xml b/app/src/main/res/drawable/ic_save.xml new file mode 100644 index 00000000..b22331a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_save.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/layout/activity_add_collaborator_to_repository.xml b/app/src/main/res/layout/activity_add_collaborator_to_repository.xml index d03c9837..030ae915 100644 --- a/app/src/main/res/layout/activity_add_collaborator_to_repository.xml +++ b/app/src/main/res/layout/activity_add_collaborator_to_repository.xml @@ -1,7 +1,7 @@ - @@ -42,24 +42,52 @@ - + style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate" + android:visibility="gone" + app:indicatorColor="?attr/progressIndicatorColor" /> + + + + + + + + + + - - diff --git a/app/src/main/res/layout/activity_add_new_team_member.xml b/app/src/main/res/layout/activity_add_new_team_member.xml index e1c438f8..298a878d 100644 --- a/app/src/main/res/layout/activity_add_new_team_member.xml +++ b/app/src/main/res/layout/activity_add_new_team_member.xml @@ -50,24 +50,43 @@ style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate" app:indicatorColor="?attr/progressIndicatorColor" /> - + android:layout_marginStart="10dp" + android:layout_marginEnd="10dp" + android:layout_marginTop="10dp" + android:layout_marginBottom="10dp"> + + + + + + + + @@ -79,6 +77,7 @@ android:textColor="?attr/inputTextColor" android:textColorHighlight="?attr/hintColor" android:textColorHint="?attr/hintColor" + android:inputType="textCapSentences" android:textSize="16sp" /> @@ -104,6 +103,9 @@ android:textColor="?attr/inputTextColor" android:textColorHighlight="?attr/hintColor" android:textColorHint="?attr/hintColor" + android:gravity="top|start" + android:scrollbars="vertical" + android:inputType="textCapSentences" android:textSize="16sp" /> @@ -207,11 +209,9 @@