From 8e86fa668d7d91ced708bd52eaa40e457fc0ee99 Mon Sep 17 00:00:00 2001 From: M M Arif Date: Fri, 23 Oct 2020 20:13:13 +0200 Subject: [PATCH] Handle popular links (#730) Fix settings layout Merge branch 'master' into deeplinks Support for all links, check gitea instance, add progress indicator Enhance account checks, improve the experience of coming from links Merge branch 'master' into deeplinks Update libs Minor layout fixes gradle update Fix show/hide views Handle pr, repos. Handle settings for no action. open issue from link Add new settings section translation ready - General for generic settings wip on handle popular links Co-authored-by: M M Arif Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: 6543 <6543@noreply.codeberg.org> Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/730 --- .idea/codeStyles/Project.xml | 17 +- README.md | 2 +- app/src/main/AndroidManifest.xml | 19 + .../gitnex/activities/DeepLinksActivity.java | 486 ++++++++++++++++++ .../activities/IssueDetailActivity.java | 18 +- .../mian/gitnex/activities/MainActivity.java | 34 +- .../gitnex/activities/RepoDetailActivity.java | 19 + .../activities/SettingsGeneralActivity.java | 94 ++++ .../mian/gitnex/database/api/DraftsApi.java | 6 +- .../gitnex/database/api/RepositoriesApi.java | 10 +- .../gitnex/database/api/UserAccountsApi.java | 23 +- .../gitnex/database/dao/UserAccountsDao.java | 3 + .../mian/gitnex/fragments/DraftsFragment.java | 3 + .../fragments/MyRepositoriesFragment.java | 43 +- .../fragments/OrganizationsFragment.java | 47 +- .../gitnex/fragments/ProfileFragment.java | 11 +- .../fragments/RepositoriesFragment.java | 42 +- .../gitnex/fragments/SettingsFragment.java | 7 + .../StarredRepositoriesFragment.java | 43 +- .../fragments/UserAccountsFragment.java | 3 + .../gitnex/helpers/StaticGlobalVariables.java | 6 +- .../mian/gitnex/interfaces/ApiInterface.java | 6 + .../main/res/layout/activity_deeplinks.xml | 131 +++++ .../res/layout/activity_settings_general.xml | 88 ++++ .../custom_assignees_selection_dialog.xml | 2 +- .../custom_explore_repositories_dialog.xml | 3 +- .../layout/custom_labels_selection_dialog.xml | 2 +- .../custom_repository_delete_dialog.xml | 2 +- .../custom_repository_transfer_dialog.xml | 2 +- app/src/main/res/layout/fragment_settings.xml | 66 ++- app/src/main/res/values/strings.xml | 10 + build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 33 files changed, 1099 insertions(+), 155 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java create mode 100644 app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java create mode 100644 app/src/main/res/layout/activity_deeplinks.xml create mode 100644 app/src/main/res/layout/activity_settings_general.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 78aa8157..ffa16517 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -19,18 +19,9 @@ - @@ -180,4 +171,4 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index 1de15309..1d0edcfb 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ddfa3c9f..b1ae7a83 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -153,12 +153,31 @@ + + + + + + + + + + + + + + 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..2e7264cd --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java @@ -0,0 +1,486 @@ +package org.mian.gitnex.activities; + +import android.content.Context; +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.PathsHelper; +import org.mian.gitnex.helpers.TinyDB; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.UrlHelper; +import org.mian.gitnex.models.GiteaVersion; +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 Context ctx = this; + private Context appCtx; + private TinyDB tinyDb; + private String currentInstance; + private String instanceToken; + + 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); + appCtx = getApplicationContext(); + tinyDb = new TinyDB(appCtx); + + 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(); + + if(userAccounts.size() > 0) { + + String hostUri; + for(int i = 0; i < userAccounts.size(); i++) { + + hostUri = userAccounts.get(i).getInstanceUrl(); + + currentInstance = userAccounts.get(i).getInstanceUrl(); + instanceToken = userAccounts.get(i).getToken(); + + if(!hostUri.contains(Objects.requireNonNull(data.getHost()))) { + + // check for valid instance + checkInstance(data); + return; + } + } + } + + // 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(!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); + tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navRepos)); + mainIntent.putExtra("launchFragmentByLinkHandler", "repos"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.organization.setOnClickListener(organization -> { + + tinyDb.putInt("defaultScreenId", 2); + tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navOrgs)); + mainIntent.putExtra("launchFragmentByLinkHandler", "org"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.notification.setOnClickListener(notification -> { + + tinyDb.putInt("defaultScreenId", 3); + tinyDb.putString("defaultScreenStr", getResources().getString(R.string.pageTitleNotifications)); + mainIntent.putExtra("launchFragmentByLinkHandler", "notification"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.explore.setOnClickListener(explore -> { + + tinyDb.putInt("defaultScreenId", 4); + tinyDb.putString("defaultScreenStr", getResources().getString(R.string.navExplore)); + mainIntent.putExtra("launchFragmentByLinkHandler", "explore"); + ctx.startActivity(mainIntent); + finish(); + }); + + viewBinding.launchApp2.setOnClickListener(launchApp2 -> { + + tinyDb.putInt("defaultScreenId", 0); + tinyDb.putString("defaultScreenStr", getResources().getString(R.string.generalDeepLinkSelectedText)); + ctx.startActivity(mainIntent); + finish(); + }); + } + } + } + else { + + ctx.startActivity(mainIntent); + finish(); + } + } + + private void checkInstance(Uri data) { + + URI host; + if(data.getPort() > 0) { + + host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https")).withPort(data.getPort()).toUri(); + } + else { + + host = UrlBuilder.fromString(UrlHelper.fixScheme(data.getHost(), "https")).toUri(); + } + + URI instanceUrl = UrlBuilder.fromUri(host).withScheme(data.getScheme().toLowerCase()).withPath(PathsHelper.join(host.getPath(), "/api/v1/")) + .toUri(); + + Call callVersion; + callVersion = RetrofitClient.getInstance(String.valueOf(instanceUrl), ctx).getApiInterface().getGiteaVersion(); + + callVersion.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull final Call callVersion, @NonNull retrofit2.Response responseVersion) { + + if(responseVersion.isSuccessful() || responseVersion.code() == 403) { + + 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 -> { + + 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(); + }); + } + } + + @Override + public void onFailure(@NonNull Call callVersion, @NonNull Throwable t) { + + Toasty.error(ctx, getResources().getString(R.string.versionUnknown)); + finish(); + } + }); + } + + private void getPullRequest(String url, String token, String repoOwner, String repoName, int index) { + + Call call = RetrofitClient + .getInstance(url, ctx) + .getApiInterface() + .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 { + + Log.e("onFailure-links-pr", String.valueOf(response.code())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure-links-pr", t.toString()); + } + }); + } + + private void goToRepoSection(String url, String token, String repoOwner, String repoName, String type) { + + Call call = RetrofitClient + .getInstance(url, ctx) + .getApiInterface() + .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 { + + Log.e("onFailure-links", String.valueOf(response.code())); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure-links", t.toString()); + } + }); + } +} 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 f6c9e732..af6cabae 100644 --- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java @@ -2,6 +2,7 @@ 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; @@ -790,7 +791,6 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt viewBinding.progressBar.setVisibility(View.GONE); } - else if(response.code() == 401) { AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), @@ -799,6 +799,22 @@ 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(); + + } } 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..ed698c57 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -79,6 +79,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig private TextView toolbarTitle; final Context ctx = this; private Context appCtx; + private static TinyDB tinyDb; private Typeface myTypeface; private String instanceUrl; @@ -101,7 +102,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig super.onCreate(savedInstanceState); appCtx = getApplicationContext(); - final TinyDB tinyDb = new TinyDB(appCtx); + tinyDb = new TinyDB(appCtx); tinyDb.putBoolean("noConnection", false); Intent mainIntent = getIntent(); @@ -347,6 +348,36 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig } } + 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")) { @@ -577,7 +608,6 @@ 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); 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..6deeae7a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java @@ -238,6 +238,25 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF } } + 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(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, instanceToken), repositoryOwner, repositoryName); 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..d71ba9bd --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsGeneralActivity.java @@ -0,0 +1,94 @@ +package org.mian.gitnex.activities; + +import android.content.Context; +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.TinyDB; +import org.mian.gitnex.helpers.Toasty; +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 Context appCtx; + private View.OnClickListener onClickListener; + + private List defaultScreen; + private static int defaultScreenSelectedChoice = 0; + + @Override + protected int getLayoutResourceId() { + + return R.layout.activity_settings_general; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + appCtx = getApplicationContext(); + + viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater()); + View view = viewBinding.getRoot(); + setContentView(view); + + TinyDB tinyDb = new TinyDB(appCtx); + + initCloseListener(); + viewBinding.close.setOnClickListener(onClickListener); + + 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(!tinyDb.getString("defaultScreenStr").isEmpty()) { + viewBinding.generalDeepLinkSelected.setText(tinyDb.getString("defaultScreenStr")); + } + + if(defaultScreenSelectedChoice == 0) { + defaultScreenSelectedChoice = tinyDb.getInt("defaultScreenId"); + } + + viewBinding.setDefaultLinkHandler.setOnClickListener(setDefaultLinkHandler -> { + + AlertDialog.Builder dlBuilder = new AlertDialog.Builder(SettingsGeneralActivity.this); + dlBuilder.setTitle(R.string.linkSelectorDialogTitle); + + if(defaultScreenSelectedChoice != -1) { + dlBuilder.setCancelable(true); + } + else { + dlBuilder.setCancelable(false); + } + + dlBuilder.setSingleChoiceItems(linksArray, defaultScreenSelectedChoice, (dialogInterfaceHomeScreen, i) -> { + + defaultScreenSelectedChoice = i; + viewBinding.generalDeepLinkSelected.setText(linksArray[i]); + tinyDb.putString("defaultScreenStr", linksArray[i]); + tinyDb.putInt("defaultScreenId", i); + + dialogInterfaceHomeScreen.dismiss(); + Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); + }); + + AlertDialog dlDialog = dlBuilder.create(); + dlDialog.show(); + + }); + + } + + private void initCloseListener() { onClickListener = view -> finish(); } +} 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..c2b5428f 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 @@ -50,7 +50,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsRepository, e.toString()); + Log.e(StaticGlobalVariables.draftsApi, e.toString()); } return draftId; @@ -66,7 +66,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsRepository, e.toString()); + Log.e(StaticGlobalVariables.draftsApi, e.toString()); } return draftId; @@ -82,7 +82,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/fragments/DraftsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/DraftsFragment.java index bda08766..44c8cbf8 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,6 +52,8 @@ public class DraftsFragment extends Fragment { ctx = getContext(); setHasOptionsMenu(true); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.titleDrafts)); + TinyDB tinyDb = new TinyDB(ctx); draftsList_ = new ArrayList<>(); 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..3903f85b 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,12 @@ 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,7 +78,7 @@ public class MyRepositoriesFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - boolean connToInternet = AppUtil.hasNetworkConnection(Objects.requireNonNull(getContext())); + boolean connToInternet = AppUtil.hasNetworkConnection(requireContext()); final View v = inflater.inflate(R.layout.fragment_my_repositories, container, false); setHasOptionsMenu(true); @@ -96,6 +92,8 @@ public class MyRepositoriesFragment extends Fragment { 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); @@ -164,29 +162,28 @@ public class MyRepositoriesFragment extends Fragment { 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(instanceUrl, 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())); + 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/OrganizationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/OrganizationsFragment.java index 5149ab3e..11dfbecf 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,12 @@ 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,7 +50,7 @@ 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())); + boolean connToInternet = AppUtil.hasNetworkConnection(requireContext()); TinyDB tinyDb = new TinyDB(getContext()); final String instanceUrl = tinyDb.getString("instanceUrl"); @@ -62,6 +59,8 @@ public class OrganizationsFragment extends Fragment { 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 +73,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() { @@ -131,21 +126,19 @@ public class OrganizationsFragment extends Fragment { 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(instanceUrl, 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,7 +146,7 @@ public class OrganizationsFragment 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/ProfileFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java index a63a0732..41c408a9 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,6 +48,8 @@ public class ProfileFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_profile, container, false); setHasOptionsMenu(true); + ((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navProfile)); + TinyDB tinyDb = new TinyDB(getContext()); BlurView blurView = v.findViewById(R.id.blurView); @@ -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/RepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java index 79968b01..ceabdfe1 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,12 @@ 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,7 +49,7 @@ 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())); + boolean connToInternet = AppUtil.hasNetworkConnection(requireContext()); final View v = inflater.inflate(R.layout.fragment_repositories, container, false); setHasOptionsMenu(true); @@ -64,6 +61,8 @@ public class RepositoriesFragment extends Fragment { 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); @@ -130,29 +129,28 @@ public class RepositoriesFragment extends Fragment { 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(instanceUrl, 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())); + 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/SettingsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java index 93bc84f5..2d8a33a1 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java @@ -12,9 +12,11 @@ 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.SettingsReportsActivity; import org.mian.gitnex.activities.SettingsSecurityActivity; import org.mian.gitnex.activities.SettingsTranslationActivity; @@ -32,6 +34,9 @@ public class SettingsFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_settings, container, false); + ((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); @@ -41,6 +46,8 @@ public class SettingsFragment extends Fragment { LinearLayout rateAppFrame = v.findViewById(R.id.rateAppFrame); LinearLayout aboutAppFrame = v.findViewById(R.id.aboutAppFrame); + generalFrame.setOnClickListener(generalFrameCall -> startActivity(new Intent(getContext(), SettingsGeneralActivity.class))); + appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsAppearanceActivity.class))); fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsFileViewerActivity.class))); 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..7be91b8b 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,12 @@ 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,7 +75,7 @@ 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())); + boolean connToInternet = AppUtil.hasNetworkConnection(requireContext()); setHasOptionsMenu(true); TinyDB tinyDb = new TinyDB(getContext()); @@ -89,6 +85,8 @@ public class StarredRepositoriesFragment extends Fragment { 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); @@ -159,29 +157,28 @@ public class StarredRepositoriesFragment extends Fragment { 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(instanceUrl, 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())); + 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/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/StaticGlobalVariables.java b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java index 1ba029a3..7c6d5c86 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java +++ b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java @@ -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; 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..e37722b2 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -58,6 +58,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); @@ -331,6 +334,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); diff --git a/app/src/main/res/layout/activity_deeplinks.xml b/app/src/main/res/layout/activity_deeplinks.xml new file mode 100644 index 00000000..c47935fd --- /dev/null +++ b/app/src/main/res/layout/activity_deeplinks.xml @@ -0,0 +1,131 @@ + + + + + + + + + +