From 98cf1a19766a5cf95a7df715028bd6172d1d853d Mon Sep 17 00:00:00 2001 From: opyale Date: Sun, 21 Mar 2021 16:56:54 +0100 Subject: [PATCH] Improve file type handling. (#841) Removing file size selection dialog in favor of hardcoded value. Adding warning to file size picker and minor improvements. Bump dependencies and gradle Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Improving credits, adding symlink and submodule icons to FilesAdapter and removing unused libraries. Minor improvements and bug fixes. Add true progress indication routine for copying streams. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Performance and memory usage improvements Notification improvements Renaming StaticGlobalVariables to Constants Overall improvements and fixes. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Add additional image formats. Adding audio and video categories. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into improve-filetype-recognition Improve file type handling. Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/841 Reviewed-by: M M Arif Co-Authored-By: opyale Co-Committed-By: opyale --- README.md | 45 +- app/build.gradle | 21 +- .../gitnex/actions/NotificationsActions.java | 5 +- .../gitnex/activities/CommitsActivity.java | 6 +- .../gitnex/activities/CreateFileActivity.java | 205 +++---- .../activities/CreateIssueActivity.java | 6 +- .../activities/CreatePullRequestActivity.java | 15 +- .../gitnex/activities/EditIssueActivity.java | 6 +- .../gitnex/activities/FileDiffActivity.java | 101 ++-- .../gitnex/activities/FileViewActivity.java | 530 +++++++++--------- .../mian/gitnex/activities/MainActivity.java | 43 +- .../activities/MergePullRequestActivity.java | 9 +- .../gitnex/activities/RepoForksActivity.java | 6 +- .../SettingsFileViewerActivity.java | 48 +- .../SettingsNotificationsActivity.java | 11 +- .../mian/gitnex/adapters/FilesAdapter.java | 64 +-- .../mian/gitnex/adapters/IssuesAdapter.java | 58 +- .../gitnex/adapters/MilestonesAdapter.java | 4 +- .../gitnex/adapters/PullRequestsAdapter.java | 119 ++-- .../gitnex/adapters/SearchIssuesAdapter.java | 37 +- .../mian/gitnex/clients/RetrofitClient.java | 29 +- .../org/mian/gitnex/core/MainApplication.java | 9 +- .../mian/gitnex/database/api/DraftsApi.java | 8 +- .../gitnex/database/api/RepositoriesApi.java | 12 +- .../gitnex/database/api/UserAccountsApi.java | 10 +- .../fragments/BottomSheetDraftsFragment.java | 4 +- .../fragments/BottomSheetReplyFragment.java | 6 +- .../ExploreRepositoriesFragment.java | 10 +- .../mian/gitnex/fragments/FilesFragment.java | 104 ++-- .../mian/gitnex/fragments/IssuesFragment.java | 12 +- .../gitnex/fragments/MilestonesFragment.java | 10 +- .../fragments/NotificationsFragment.java | 6 +- .../gitnex/fragments/ProfileFragment.java | 31 +- .../fragments/PullRequestsFragment.java | 10 +- .../gitnex/fragments/RepoInfoFragment.java | 170 ++---- .../gitnex/fragments/SettingsFragment.java | 1 + .../java/org/mian/gitnex/helpers/AppUtil.java | 69 ++- .../mian/gitnex/helpers/Authorization.java | 8 + .../mian/gitnex/helpers/ColorInverter.java | 46 +- .../org/mian/gitnex/helpers/Constants.java | 61 ++ .../org/mian/gitnex/helpers/ParseDiff.java | 2 +- .../gitnex/helpers/StaticGlobalVariables.java | 53 -- .../helpers/highlightjs/HighlightJsView.java | 15 +- .../gitnex/notifications/Notifications.java | 66 ++- .../notifications/NotificationsWorker.java | 92 +-- .../mian/gitnex/views/ReactionSpinner.java | 3 +- app/src/main/res/drawable/ic_directory.xml | 9 +- app/src/main/res/drawable/ic_file.xml | 16 +- app/src/main/res/drawable/ic_question.xml | 24 +- app/src/main/res/drawable/ic_submodule.xml | 10 + app/src/main/res/drawable/ic_symlink.xml | 10 + .../main/res/layout/activity_file_view.xml | 26 +- .../layout/activity_settings_fileviewer.xml | 1 - app/src/main/res/layout/fragment_files.xml | 3 +- app/src/main/res/layout/fragment_profile.xml | 106 ++-- .../main/res/layout/layout_last_commit.xml | 61 ++ app/src/main/res/layout/list_issues.xml | 125 ++--- app/src/main/res/layout/list_pr.xml | 161 ++---- app/src/main/res/layout/nav_header.xml | 150 ++--- app/src/main/res/values/strings.xml | 16 +- build.gradle | 2 +- 61 files changed, 1387 insertions(+), 1519 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/helpers/Constants.java delete mode 100644 app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java create mode 100644 app/src/main/res/drawable/ic_submodule.xml create mode 100644 app/src/main/res/drawable/ic_symlink.xml create mode 100644 app/src/main/res/layout/layout_last_commit.xml diff --git a/README.md b/README.md index 356c9634..66542253 100644 --- a/README.md +++ b/README.md @@ -69,26 +69,31 @@ We use [Crowdin](https://crowdin.com/project/gitnex) for translation. If your la Thanks to all the open source libraries, contributors and donators. #### Open source libraries -- Retrofit -- Gson -- Okhttp -- Picasso -- Markwon -- Prism4j -- Prettytime -- Amulyakhare/textdrawable -- Vdurmont/emoji-java -- Pes/materialcolorpicker -- HamidrezaAmz/BreadcrumbsView -- Chrisbanes/PhotoView -- Pddstudio/highlightjs-android -- Apache/commons-io -- Caverock/androidsvg -- Droidsonroids.gif/android-gif-drawable -- Barteksc/androidPdfViewer -- Ge0rg/memorizingTrustManager -- Dimezis/blurView -- Mikaelhg/urlbuilder +- [square/retrofit](https://github.com/square/retrofit) +- [google/gson](https://github.com/google/gson) +- [square/okhttp](https://github.com/square/okhttp) +- [square/picasso](https://github.com/square/picasso) +- [wasabeef/picasso-transformations](https://github.com/wasabeef/picasso-transformations) +- [cats-oss/android-gpuimage](https://github.com/cats-oss/android-gpuimage) +- [noties/Markwon](https://github.com/noties/Markwon) +- [noties/Prism4j](https://github.com/noties/Prism4j) +- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime) +- [amulyakhare/TextDrawable](https://github.com/amulyakhare/TextDrawable) +- [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java) +- [Pes8/android-material-color-picker-dialog](https://github.com/Pes8/android-material-color-picker-dialog) +- [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView) +- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView) +- [PDDStudio/highlightjs-android](https://github.com/PDDStudio/highlightjs-android) +- [apache/commons](https://github.com/apache/commons-io) +- [barteksc/AndroidPdfViewer](https://github.com/barteksc/AndroidPdfViewer) +- [ge0rg/MemorizingTrustManager](https://github.com/ge0rg/MemorizingTrustManager) +- [mikaelhg/urlbuilder](https://github.com/mikaelhg/urlbuilder) +- [ACRA/acra](https://github.com/ACRA/acra) + +#### Icon sets +- [feathericons/feather](https://github.com/feathericons/feather) +- [primer/octicons](https://github.com/primer/octicons) +- [google/material-design-icons](https://github.com/google/material-design-icons) [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) diff --git a/app/build.gradle b/app/build.gradle index 3cc8fd32..a7fd801b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,7 +30,7 @@ android { release { minifyEnabled false shrinkResources false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } lintOptions { @@ -55,7 +55,7 @@ configurations { dependencies { def lifecycle_version = '2.3.0' - def markwon_version = '4.6.1' + def markwon_version = '4.6.2' def work_version = "2.5.0" def acra = "5.7.0" @@ -65,17 +65,19 @@ dependencies { 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.1' + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2' implementation "com.google.code.gson:gson:2.8.6" implementation "com.squareup.picasso:picasso:2.71828" + implementation 'jp.wasabeef:picasso-transformations:2.4.0' + implementation 'jp.co.cyberagent.android:gpuimage:2.1.0' implementation "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1" implementation 'com.squareup.retrofit2:retrofit:2.9.0' 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 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2' implementation 'org.ocpsoft.prettytime:prettytime:5.0.0.Final' implementation "com.pes.materialcolorpicker:library:1.2.5" implementation "io.noties.markwon:core:$markwon_version" @@ -94,11 +96,9 @@ dependencies { 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.21" implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" implementation "commons-io:commons-io:20030203.000550" - implementation 'org.apache.commons:commons-lang3:3.11' + implementation 'org.apache.commons:commons-lang3:3.12.0' implementation "com.github.chrisbanes:PhotoView:2.3.0" implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1" implementation "ch.acra:acra-mail:$acra" @@ -107,11 +107,10 @@ dependencies { 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.4" implementation "io.mikael:urlbuilder:2.0.9" implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2" - implementation "org.codeberg.gitnex:tea4j:1.0.1" - coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1" + implementation "org.codeberg.gitnex:tea4j:1.0.5" + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5" implementation 'androidx.biometric:biometric:1.1.0' } 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 308a3f40..8c5e2946 100644 --- a/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/NotificationsActions.java @@ -7,7 +7,6 @@ import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.TinyDB; import java.io.IOException; import java.util.Date; -import okhttp3.ResponseBody; import retrofit2.Call; /** @@ -35,7 +34,7 @@ public class NotificationsActions { public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException { - Call call = RetrofitClient.getApiInterface(context) + Call call = RetrofitClient.getApiInterface(context) .markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name()); if(!call.execute().isSuccessful()) { @@ -46,7 +45,7 @@ public class NotificationsActions { public boolean setAllNotificationsRead(Date date) throws IOException { - Call call = RetrofitClient.getApiInterface(context) + 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/activities/CommitsActivity.java b/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java index db4a661d..75c27cda 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CommitsActivity.java @@ -24,7 +24,7 @@ import org.mian.gitnex.adapters.CommitsAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.ActivityCommitsBinding; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; @@ -43,7 +43,7 @@ public class CommitsActivity extends BaseActivity { private TextView noData; private ProgressBar progressBar; private String TAG = "CommitsActivity"; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private int pageSize = 1; private RecyclerView recyclerView; @@ -85,7 +85,7 @@ public class CommitsActivity 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; + resultLimit = Constants.resultLimitNewGiteaInstances; } recyclerView = activityCommitsBinding.recyclerView; 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 f8cf0c8f..3ce413a5 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java @@ -8,10 +8,6 @@ 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.EditText; -import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import com.google.gson.JsonElement; @@ -38,16 +34,7 @@ import retrofit2.Callback; public class CreateFileActivity extends BaseActivity { - public ImageView closeActivity; - private View.OnClickListener onClickListener; - private Button newFileCreate; - - private EditText newFileName; - private EditText newFileContent; - private EditText newFileCommitMessage; - private AutoCompleteTextView newFileBranches; - private String filePath; - private String fileSha; + private ActivityCreateFileBinding binding; public static final int FILE_ACTION_CREATE = 0; public static final int FILE_ACTION_DELETE = 1; @@ -55,6 +42,9 @@ public class CreateFileActivity extends BaseActivity { private int fileAction = FILE_ACTION_CREATE; + private String filePath; + private String fileSha; + private final List branches = new ArrayList<>(); private String repoOwner; @@ -66,154 +56,127 @@ public class CreateFileActivity extends BaseActivity { super.onCreate(savedInstanceState); - ActivityCreateFileBinding activityCreateFileBinding = ActivityCreateFileBinding.inflate(getLayoutInflater()); - setContentView(activityCreateFileBinding.getRoot()); - - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + binding = ActivityCreateFileBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); String repoFullName = tinyDB.getString("repoFullName"); String[] parts = repoFullName.split("/"); repoOwner = parts[0]; repoName = parts[1]; - closeActivity = activityCreateFileBinding.close; - newFileName = activityCreateFileBinding.newFileName; - newFileContent = activityCreateFileBinding.newFileContent; - newFileCommitMessage = activityCreateFileBinding.newFileCommitMessage; - TextView toolbarTitle = activityCreateFileBinding.toolbarTitle; + TextView toolbarTitle = binding.toolbarTitle; - newFileName.requestFocus(); - assert imm != null; - imm.showSoftInput(newFileName, InputMethodManager.SHOW_IMPLICIT); + binding.newFileName.requestFocus(); - initCloseListener(); + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + assert inputMethodManager != null; + inputMethodManager.showSoftInput(binding.newFileName, InputMethodManager.SHOW_IMPLICIT); - closeActivity.setOnClickListener(onClickListener); - - newFileCreate = activityCreateFileBinding.newFileCreate; - newFileContent.setOnTouchListener((touchView, motionEvent) -> { + binding.close.setOnClickListener(view -> finish()); + binding.newFileContent.setOnTouchListener((touchView, motionEvent) -> { touchView.getParent().requestDisallowInterceptTouchEvent(true); - if ((motionEvent.getAction() & MotionEvent.ACTION_UP) != 0 && (motionEvent.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + 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", FILE_ACTION_DELETE) == FILE_ACTION_DELETE) { fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_DELETE); - filePath = getIntent().getStringExtra("filePath"); - String fileContents = getIntent().getStringExtra("fileContents"); fileSha = getIntent().getStringExtra("fileSha"); toolbarTitle.setText(getString(R.string.deleteFileText, filePath)); - newFileCreate.setText(R.string.deleteFile); - newFileName.setText(filePath); - newFileName.setEnabled(false); - newFileName.setFocusable(false); + binding.newFileCreate.setText(R.string.deleteFile); - newFileContent.setText(fileContents); - newFileContent.setEnabled(false); - newFileContent.setFocusable(false); + binding.newFileNameLayout.setVisibility(View.GONE); + binding.newFileContentLayout.setVisibility(View.GONE); } if(getIntent().getStringExtra("filePath") != null && getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT) == FILE_ACTION_EDIT) { fileAction = getIntent().getIntExtra("fileAction", FILE_ACTION_EDIT); - filePath = getIntent().getStringExtra("filePath"); - String fileContents = getIntent().getStringExtra("fileContents"); fileSha = getIntent().getStringExtra("fileSha"); toolbarTitle.setText(getString(R.string.editFileText, filePath)); - newFileCreate.setText(R.string.editFile); - newFileName.setText(filePath); - newFileName.setEnabled(false); - newFileName.setFocusable(false); + binding.newFileCreate.setText(R.string.editFile); + binding.newFileName.setText(filePath); + binding.newFileName.setEnabled(false); + binding.newFileName.setFocusable(false); - newFileContent.setText(fileContents); + binding.newFileContent.setText(getIntent().getStringExtra("fileContents")); } - initCloseListener(); - closeActivity.setOnClickListener(onClickListener); - - newFileBranches = activityCreateFileBinding.newFileBranches; getBranches(repoOwner, repoName); disableProcessButton(); NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx); - networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> newFileCreate.setEnabled(hasNetworkConnection)); + networkStatusObserver.registerNetworkStatusListener(binding.newFileCreate::setEnabled); - newFileCreate.setOnClickListener(createFileListener); + binding.newFileCreate.setOnClickListener(v -> processNewFile()); } - private final View.OnClickListener createFileListener = v -> processNewFile(); - private void processNewFile() { - boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); - - String newFileName_ = newFileName.getText().toString(); - String newFileContent_ = newFileContent.getText().toString(); - String newFileBranchName_ = newFileBranches.getText().toString(); - String newFileCommitMessage_ = newFileCommitMessage.getText().toString(); - - if(!connToInternet) { + String newFileName = binding.newFileName.getText() != null ? binding.newFileName.getText().toString() : ""; + String newFileContent = binding.newFileContent.getText() != null ? binding.newFileContent.getText().toString() : ""; + String newFileBranchName = binding.newFileBranches.getText() != null ? binding.newFileBranches.getText().toString() : ""; + String newFileCommitMessage = binding.newFileCommitMessage.getText() != null ? binding.newFileCommitMessage.getText().toString() : ""; + if(!AppUtil.hasNetworkConnection(appCtx)) { Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); return; } - if(newFileName_.equals("") || newFileContent_.equals("") || newFileCommitMessage_.equals("")) { - + if(((newFileName.isEmpty() || newFileContent.isEmpty()) && fileAction != FILE_ACTION_DELETE) || newFileCommitMessage.isEmpty()) { Toasty.error(ctx, getString(R.string.newFileRequiredFields)); return; } - if(!AppUtil.checkStringsWithDash(newFileBranchName_)) { - + if(!AppUtil.checkStringsWithDash(newFileBranchName)) { Toasty.error(ctx, getString(R.string.newFileInvalidBranchName)); return; } - if(newFileCommitMessage_.length() > 255) { - + if(newFileCommitMessage.length() > 255) { Toasty.warning(ctx, getString(R.string.newFileCommitMessageError)); + return; } - else { - disableProcessButton(); + disableProcessButton(); - switch(fileAction) { + switch(fileAction) { - case FILE_ACTION_CREATE: - createNewFile(Authorization.get(ctx), repoOwner, repoName, newFileName_, AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_); - break; + case FILE_ACTION_CREATE: + createNewFile(repoOwner, repoName, newFileName, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName); + break; - case FILE_ACTION_DELETE: - deleteFile(Authorization.get(ctx), repoOwner, repoName, filePath, newFileCommitMessage_, newFileBranchName_, fileSha); - break; + case FILE_ACTION_DELETE: + deleteFile(repoOwner, repoName, filePath, newFileCommitMessage, newFileBranchName, fileSha); + break; - case FILE_ACTION_EDIT: - editFile(Authorization.get(ctx), repoOwner, repoName, filePath, - AppUtil.encodeBase64(newFileContent_), newFileCommitMessage_, newFileBranchName_, fileSha); - break; + case FILE_ACTION_EDIT: + editFile(repoOwner, repoName, filePath, AppUtil.encodeBase64(newFileContent), newFileCommitMessage, newFileBranchName, fileSha); + break; - } } } - private void createNewFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName) { + private void createNewFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName) { NewFile createNewFileJsonStr = branches.contains(branchName) ? new NewFile(branchName, fileContent, fileCommitMessage, "") : @@ -221,7 +184,7 @@ public class CreateFileActivity extends BaseActivity { Call call = RetrofitClient .getApiInterface(ctx) - .createNewFile(token, repoOwner, repoName, fileName, createNewFileJsonStr); + .createNewFile(Authorization.get(ctx), repoOwner, repoName, fileName, createNewFileJsonStr); call.enqueue(new Callback() { @@ -268,7 +231,7 @@ public class CreateFileActivity extends BaseActivity { } - private void deleteFile(final String token, String repoOwner, String repoName, String fileName, String fileCommitMessage, String branchName, String fileSha) { + private void deleteFile(String repoOwner, String repoName, String fileName, String fileCommitMessage, String branchName, String fileSha) { DeleteFile deleteFileJsonStr = branches.contains(branchName) ? new DeleteFile(branchName, fileCommitMessage, "", fileSha) : @@ -276,42 +239,42 @@ public class CreateFileActivity extends BaseActivity { Call call = RetrofitClient .getApiInterface(ctx) - .deleteFile(token, repoOwner, repoName, fileName, deleteFileJsonStr); + .deleteFile(Authorization.get(ctx), repoOwner, repoName, fileName, deleteFileJsonStr); call.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if(response.code() == 200) { + switch(response.code()) { - enableProcessButton(); - Toasty.info(ctx, getString(R.string.deleteFileMessage, tinyDB.getString("repoBranch"))); - getIntent().removeExtra("filePath"); - getIntent().removeExtra("fileSha"); - getIntent().removeExtra("fileContents"); - finish(); - } - else if(response.code() == 401) { + case 200: + enableProcessButton(); + Toasty.info(ctx, getString(R.string.deleteFileMessage, tinyDB.getString("repoBranch"))); + getIntent().removeExtra("filePath"); + getIntent().removeExtra("fileSha"); + getIntent().removeExtra("fileContents"); + finish(); + break; - 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) { + case 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)); + break; + case 404: enableProcessButton(); Toasty.info(ctx, getString(R.string.apiNotFound)); - } - else { + break; + default: enableProcessButton(); Toasty.info(ctx, getString(R.string.genericError)); - } + break; + } } @@ -325,7 +288,7 @@ public class CreateFileActivity extends BaseActivity { } - private void editFile(final String token, String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName, String fileSha) { + private void editFile(String repoOwner, String repoName, String fileName, String fileContent, String fileCommitMessage, String branchName, String fileSha) { EditFile editFileJsonStr = branches.contains(branchName) ? new EditFile(branchName, fileCommitMessage, "", fileSha, fileContent) : @@ -333,7 +296,7 @@ public class CreateFileActivity extends BaseActivity { Call call = RetrofitClient .getApiInterface(ctx) - .editFile(token, repoOwner, repoName, fileName, editFileJsonStr); + .editFile(Authorization.get(ctx), repoOwner, repoName, fileName, editFileJsonStr); call.enqueue(new Callback() { @@ -402,8 +365,8 @@ public class CreateFileActivity extends BaseActivity { ArrayAdapter adapter = new ArrayAdapter<>(CreateFileActivity.this, R.layout.list_spinner_items, branches); - newFileBranches.setAdapter(adapter); - newFileBranches.setText(tinyDB.getString("repoBranch"), false); + binding.newFileBranches.setAdapter(adapter); + binding.newFileBranches.setText(tinyDB.getString("repoBranch"), false); enableProcessButton(); @@ -419,19 +382,7 @@ public class CreateFileActivity extends BaseActivity { } - private void initCloseListener() { - - onClickListener = view -> finish(); - } - - private void disableProcessButton() { - - newFileCreate.setEnabled(false); - } - - private void enableProcessButton() { - - newFileCreate.setEnabled(true); - } + private void disableProcessButton() { binding.newFileCreate.setEnabled(false); } + private void enableProcessButton() { binding.newFileCreate.setEnabled(true); } } 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 12b0f449..aa1e9d46 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java @@ -30,7 +30,7 @@ import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; @@ -51,7 +51,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis private CustomLabelsSelectionDialogBinding labelsBinding; private CustomAssigneesSelectionDialogBinding assigneesBinding; private View.OnClickListener onClickListener; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private Dialog dialogLabels; private Dialog dialogAssignees; private String labelsSetter; @@ -93,7 +93,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis // require gitea 1.12 or higher if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } viewBinding.newIssueTitle.requestFocus(); 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 a274d2ff..5c7256ed 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java @@ -24,13 +24,12 @@ import org.mian.gitnex.databinding.ActivityCreatePrBinding; 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.Constants; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; import java.util.Calendar; import java.util.List; -import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; @@ -43,7 +42,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis private View.OnClickListener onClickListener; private ActivityCreatePrBinding viewBinding; private CustomLabelsSelectionDialogBinding labelsBinding; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private Dialog dialogLabels; private String labelsSetter; private List labelsIds = new ArrayList<>(); @@ -80,7 +79,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis // require gitea 1.12 or higher if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } viewBinding.prBody.setOnTouchListener((touchView, motionEvent) -> { @@ -165,14 +164,14 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis CreatePullRequest createPullRequest = new CreatePullRequest(prTitle, prDescription, loginUid, mergeInto, pullFrom, milestoneId, dueDate, assignees, labelsIds); - Call transferCall = RetrofitClient + Call transferCall = RetrofitClient .getApiInterface(appCtx) .createPullRequest(instanceToken, repoOwner, repoName, createPullRequest); - transferCall.enqueue(new Callback() { + transferCall.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { disableProcessButton(); @@ -199,7 +198,7 @@ public class CreatePullRequestActivity extends BaseActivity implements LabelsLis } @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { + public void onFailure(@NonNull Call call, @NonNull Throwable t) { enableProcessButton(); Toasty.error(ctx, getString(R.string.genericServerResponseError)); 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 9e813b5e..5ec7dea8 100644 --- a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java @@ -27,7 +27,7 @@ import org.mian.gitnex.databinding.ActivityEditIssueBinding; 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.Constants; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import java.text.DateFormat; @@ -45,7 +45,7 @@ import retrofit2.Callback; public class EditIssueActivity extends BaseActivity implements View.OnClickListener { private View.OnClickListener onClickListener; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private EditText editIssueTitle; private EditText editIssueDescription; @@ -93,7 +93,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe // if gitea is 1.12 or higher use the new limit if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } editIssueTitle.requestFocus(); 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 b24ded72..a186dc06 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileDiffActivity.java @@ -1,13 +1,11 @@ package org.mian.gitnex.activities; import android.os.Bundle; -import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import org.gitnex.tea4j.models.FileDiffView; import org.mian.gitnex.R; @@ -15,6 +13,7 @@ import org.mian.gitnex.adapters.FilesDiffAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.ActivityFileDiffBinding; import org.mian.gitnex.helpers.AlertDialogs; +import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.ParseDiff; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; @@ -23,7 +22,7 @@ import java.io.IOException; import java.util.List; import okhttp3.ResponseBody; import retrofit2.Call; -import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -52,8 +51,6 @@ public class FileDiffActivity extends BaseActivity { String[] parts = repoFullName.split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); ImageView closeActivity = activityFileDiffBinding.close; toolbarTitle = activityFileDiffBinding.toolbarTitle; @@ -71,80 +68,69 @@ public class FileDiffActivity extends BaseActivity { String pullIndex = tinyDb.getString("issueNumber"); boolean apiCall = !new Version(tinyDb.getString("giteaVersion")).less("1.13.0"); - getPullDiffContent(repoOwner, repoName, pullIndex, instanceToken, apiCall); + getPullDiffContent(repoOwner, repoName, pullIndex, apiCall); } - private void getPullDiffContent(String owner, String repo, String pullIndex, String token, boolean apiCall) { + private void getPullDiffContent(String owner, String repo, String pullIndex, boolean apiCall) { - Call call; - if(apiCall) { + Thread thread = new Thread(() -> { - call = RetrofitClient.getApiInterface(ctx).getPullDiffContent(token, owner, repo, pullIndex); - } - else { + Call call = apiCall ? + RetrofitClient.getApiInterface(ctx).getPullDiffContent(Authorization.get(ctx), owner, repo, pullIndex) : + RetrofitClient.getWebInterface(ctx).getPullDiffContent(Authorization.getWeb(ctx), owner, repo, pullIndex); - call = RetrofitClient.getWebInterface(ctx).getPullDiffContent(owner, repo, pullIndex); - } + try { - call.enqueue(new Callback() { + Response response = call.execute(); + assert response.body() != null; - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + switch(response.code()) { - if(response.code() == 200) { + case 200: + List fileDiffViews = ParseDiff.getFileDiffViewArray(response.body().string()); - try { + int filesCount = fileDiffViews.size(); - assert response.body() != null; + String toolbarTitleText = (filesCount > 1) ? + getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)) : + getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount)); - List fileContentsArray = ParseDiff.getFileDiffViewArray(response.body().string()); + FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileDiffViews); - int filesCount = fileContentsArray.size(); - if(filesCount > 1) { + runOnUiThread(() -> { + toolbarTitle.setText(toolbarTitleText); + mListView.setAdapter(adapter); + mProgressBar.setVisibility(View.GONE); + }); + break; - toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount))); - } - else { + case 401: + AlertDialogs.authorizationTokenRevokedDialog(ctx, + getString(R.string.alertDialogTokenRevokedTitle), + getString(R.string.alertDialogTokenRevokedMessage), + getString(R.string.alertDialogTokenRevokedCopyNegativeButton), + getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + break; - toolbarTitle.setText(getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount))); - } + case 403: + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + break; - FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileContentsArray); - mListView.setAdapter(adapter); + case 404: + Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); + break; - mProgressBar.setVisibility(View.GONE); - } - catch(IOException e) { + default: + Toasty.error(ctx, getString(R.string.labelGeneralError)); - e.printStackTrace(); - } } - else if(response.code() == 401) { + } catch(IOException ignored) {} - 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 - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - - Log.e("onFailure", t.toString()); - } }); + thread.start(); + } private void initCloseListener() { @@ -153,6 +139,7 @@ public class FileDiffActivity extends BaseActivity { getIntent().removeExtra("singleFileName"); finish(); + }; } 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 e4e5c35d..a085b6fe 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java @@ -1,29 +1,21 @@ package org.mian.gitnex.activities; import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; import android.content.Intent; import android.graphics.Typeface; -import android.net.Uri; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; -import android.util.Base64; -import android.util.Log; import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import com.github.barteksc.pdfviewer.PDFView; +import androidx.core.app.NotificationCompat; import com.github.barteksc.pdfviewer.util.FitPolicy; -import com.github.chrisbanes.photoview.PhotoView; import com.vdurmont.emoji.EmojiParser; import org.apache.commons.io.FileUtils; import org.gitnex.tea4j.models.Files; @@ -33,19 +25,19 @@ import org.mian.gitnex.databinding.ActivityFileViewBinding; import org.mian.gitnex.fragments.BottomSheetFileViewerFragment; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Images; 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; -import java.io.File; +import org.mian.gitnex.notifications.Notifications; import java.io.IOException; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.Objects; +import java.util.Arrays; +import okhttp3.ResponseBody; import retrofit2.Call; -import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -53,74 +45,38 @@ import retrofit2.Callback; public class FileViewActivity extends BaseActivity implements BottomSheetFileViewerFragment.BottomSheetListener { - private View.OnClickListener onClickListener; - private TextView singleFileContents; - private LinearLayout singleFileContentsFrame; - private HighlightJsView singleCodeContents; - private PhotoView imageView; - private ProgressBar mProgressBar; - private byte[] imageData; - private PDFView pdfView; - private LinearLayout pdfViewFrame; - private byte[] decodedPdf; + private ActivityFileViewBinding binding; private Boolean pdfNightMode; - private String singleFileName; - private String fileSha; + + private Files file; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ActivityFileViewBinding activityFileViewBinding = ActivityFileViewBinding.inflate(getLayoutInflater()); - setContentView(activityFileViewBinding.getRoot()); + binding = ActivityFileViewBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); - Toolbar toolbar = activityFileViewBinding.toolbar; - setSupportActionBar(toolbar); + setSupportActionBar(binding.toolbar); + + tinyDB.putBoolean("enableMarkdownInFileView", false); + + file = (Files) getIntent().getSerializableExtra("file"); + + binding.close.setOnClickListener(view -> finish()); + + binding.toolbarTitle.setMovementMethod(new ScrollingMovementMethod()); + binding.toolbarTitle.setText(file.getPath()); 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 loginUid = tinyDB.getString("loginUid"); - final String instanceToken = "token " + tinyDB.getString(loginUid + "-token"); + String repoOwner = parts[0]; + String repoName = parts[1]; - tinyDB.putBoolean("enableMarkdownInFileView", false); + getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch); - ImageView closeActivity = activityFileViewBinding.close; - singleFileContents = activityFileViewBinding.singleFileContents; - singleCodeContents = activityFileViewBinding.singleCodeContents; - imageView = activityFileViewBinding.imageView; - mProgressBar = activityFileViewBinding.progressBar; - pdfView = activityFileViewBinding.pdfView; - pdfViewFrame = activityFileViewBinding.pdfViewFrame; - singleFileContentsFrame = activityFileViewBinding.singleFileContentsFrame; - - singleFileName = getIntent().getStringExtra("singleFileName"); - - TextView toolbar_title = activityFileViewBinding.toolbarTitle; - toolbar_title.setMovementMethod(new ScrollingMovementMethod()); - - initCloseListener(); - closeActivity.setOnClickListener(onClickListener); - - 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(instanceToken, repoOwner, repoName, singleFileName, repoBranch); } @Override @@ -128,166 +84,201 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie super.onResume(); - String repoFullName = tinyDB.getString("repoFullName"); - String repoBranch = tinyDB.getString("repoBranch"); - String[] parts = repoFullName.split("/"); - String repoOwner = parts[0]; - String repoName = parts[1]; - String loginUid = tinyDB.getString("loginUid"); - String instanceToken = "token " + tinyDB.getString(loginUid + "-token"); - if(tinyDB.getBoolean("fileModified")) { - getSingleFileContents(instanceToken, repoOwner, repoName, singleFileName, repoBranch); + String repoFullName = tinyDB.getString("repoFullName"); + String repoBranch = tinyDB.getString("repoBranch"); + String[] parts = repoFullName.split("/"); + String repoOwner = parts[0]; + String repoName = parts[1]; + + getSingleFileContents(repoOwner, repoName, file.getPath(), repoBranch); tinyDB.putBoolean("fileModified", false); + } } + private void getSingleFileContents(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) { + Thread thread = new Thread(() -> { - Call call = RetrofitClient.getApiInterface(ctx).getSingleFileContents(token, owner, repo, filename, ref); + Call call = RetrofitClient + .getWebInterface(ctx) + .getFileContents(Authorization.getWeb(ctx), owner, repo, ref, filename); - call.enqueue(new Callback() { + try { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + Response response = call.execute(); if(response.code() == 200) { - assert response.body() != null; + ResponseBody responseBody = response.body(); - if(!response.body().getContent().equals("")) { + if(responseBody != null) { + + runOnUiThread(() -> binding.progressBar.setVisibility(View.GONE)); String fileExtension = FileUtils.getExtension(filename); - mProgressBar.setVisibility(View.GONE); - fileSha = response.body().getSha(); - - // download file meta - tinyDB.putString("downloadFileName", filename); - tinyDB.putString("downloadFileContents", response.body().getContent()); - - boolean unknown = false; + boolean processable = false; switch(AppUtil.getFileType(fileExtension)) { case IMAGE: - singleFileContentsFrame.setVisibility(View.GONE); - singleCodeContents.setVisibility(View.GONE); - pdfViewFrame.setVisibility(View.GONE); - imageView.setVisibility(View.VISIBLE); + // See https://developer.android.com/guide/topics/media/media-formats#core + if(Arrays.asList("bmp", "gif", "jpg", "jpeg", "png", "webp", "heic", "heif").contains(fileExtension.toLowerCase())) { - imageData = Base64.decode(response.body().getContent(), Base64.DEFAULT); - imageView.setImageBitmap(Images.scaleImage(imageData, 1920)); + processable = true; + + byte[] pictureBytes = responseBody.bytes(); + + runOnUiThread(() -> { + + binding.contents.setVisibility(View.GONE); + binding.pdfViewFrame.setVisibility(View.GONE); + binding.markdownFrame.setVisibility(View.GONE); + + binding.photoView.setVisibility(View.VISIBLE); + binding.photoView.setImageBitmap(Images.scaleImage(pictureBytes, 1920)); + + }); + } break; + + case UNKNOWN: case TEXT: - imageView.setVisibility(View.GONE); - singleFileContentsFrame.setVisibility(View.GONE); - pdfViewFrame.setVisibility(View.GONE); - singleCodeContents.setVisibility(View.VISIBLE); - - 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); - + if(file.getSize() > Constants.maximumFileViewerSize) { + break; } - singleCodeContents.setSource(AppUtil.decodeBase64(response.body().getContent())); + processable = true; + + String text = responseBody.string(); + + runOnUiThread(() -> { + + binding.photoView.setVisibility(View.GONE); + binding.markdownFrame.setVisibility(View.GONE); + binding.pdfViewFrame.setVisibility(View.GONE); + + switch(tinyDB.getInt("fileviewerSourceCodeThemeId")) { + + case 1: binding.contents.setTheme(Theme.ARDUINO_LIGHT); break; + case 2: binding.contents.setTheme(Theme.GITHUB); break; + case 3: binding.contents.setTheme(Theme.FAR); break; + case 4: binding.contents.setTheme(Theme.IR_BLACK); break; + case 5: binding.contents.setTheme(Theme.ANDROID_STUDIO); break; + + default: binding.contents.setTheme(Theme.MONOKAI_SUBLIME); + + } + + binding.contents.setVisibility(View.VISIBLE); + binding.contents.setContent(text); + + }); break; + case DOCUMENT: if(fileExtension.equalsIgnoreCase("pdf")) { - imageView.setVisibility(View.GONE); - singleFileContentsFrame.setVisibility(View.GONE); - singleCodeContents.setVisibility(View.GONE); - pdfViewFrame.setVisibility(View.VISIBLE); + processable = true; - pdfNightMode = tinyDB.getBoolean("enablePdfMode"); - decodedPdf = Base64.decode(response.body().getContent(), Base64.DEFAULT); + byte[] documentBytes = responseBody.bytes(); - 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(); + runOnUiThread(() -> { + + binding.photoView.setVisibility(View.GONE); + binding.markdownFrame.setVisibility(View.GONE); + binding.contents.setVisibility(View.GONE); + + pdfNightMode = tinyDB.getBoolean("enablePdfMode"); + + binding.pdfViewFrame.setVisibility(View.VISIBLE); + binding.pdfView.fromBytes(documentBytes) + .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(); + + }); } - else { - unknown = true; - } break; - case UNKNOWN: - default: - unknown = true; - break; } - if(unknown) { // While the file could still be non-binary, + if(!processable) { // While the file could still be non-binary, // it's better we don't show it (to prevent any crashes and/or unwanted behavior) and let the user download it instead. - imageView.setVisibility(View.GONE); - singleCodeContents.setVisibility(View.GONE); - pdfViewFrame.setVisibility(View.GONE); - singleFileContentsFrame.setVisibility(View.VISIBLE); + responseBody.close(); - singleFileContents.setText(getString(R.string.excludeFilesInFileViewer)); - singleFileContents.setGravity(Gravity.CENTER); - singleFileContents.setTypeface(null, Typeface.BOLD); + runOnUiThread(() -> { + + binding.photoView.setVisibility(View.GONE); + binding.contents.setVisibility(View.GONE); + binding.pdfViewFrame.setVisibility(View.GONE); + + binding.markdownFrame.setVisibility(View.VISIBLE); + binding.markdown.setText(getString(R.string.excludeFilesInFileViewer)); + binding.markdown.setGravity(Gravity.CENTER); + binding.markdown.setTypeface(null, Typeface.BOLD); + + }); } - } - else { + } else { + + runOnUiThread(() -> { + binding.markdown.setText(""); + binding.progressBar.setVisibility(View.GONE); + }); + + } + } else { + + switch(response.code()) { + + case 401: + AlertDialogs.authorizationTokenRevokedDialog(ctx, + getResources().getString(R.string.alertDialogTokenRevokedTitle), + getResources().getString(R.string.alertDialogTokenRevokedMessage), + getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), + 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, getString(R.string.labelGeneralError)); - singleFileContents.setText(""); - mProgressBar.setVisibility(View.GONE); } } - else if(response.code() == 401) { + } catch(IOException ignored) {} - 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 - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - - Log.e("onFailure", t.toString()); - } }); + thread.start(); + } @Override @@ -297,11 +288,11 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie inflater.inflate(R.menu.generic_nav_dotted_menu, menu); inflater.inflate(R.menu.files_view_menu, menu); - String fileExtension = FileUtils.getExtension(singleFileName); + if(!FileUtils.getExtension(file.getName()) + .equalsIgnoreCase("md")) { - if(!fileExtension.equalsIgnoreCase("md")) { - - menu.getItem(0).setVisible(false); + menu.getItem(0) + .setVisible(false); } return true; @@ -316,35 +307,36 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie finish(); return true; - } - else if(id == R.id.genericMenu) { + + } 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, EmojiParser.parseToUnicode(AppUtil.decodeBase64(tinyDB.getString("downloadFileContents"))), singleFileContents); + } else if(id == R.id.markdown) { if(!tinyDB.getBoolean("enableMarkdownInFileView")) { - singleCodeContents.setVisibility(View.GONE); - singleFileContentsFrame.setVisibility(View.VISIBLE); - singleFileContents.setVisibility(View.VISIBLE); - tinyDB.putBoolean("enableMarkdownInFileView", true); - } - else { + new Markdown(ctx, EmojiParser.parseToUnicode(binding.contents.getContent()), binding.markdown); + + binding.contents.setVisibility(View.GONE); + binding.markdownFrame.setVisibility(View.VISIBLE); + + tinyDB.putBoolean("enableMarkdownInFileView", true); + + } else { + + binding.markdownFrame.setVisibility(View.GONE); + binding.contents.setVisibility(View.VISIBLE); - 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 { + + } else { return super.onOptionsItemSelected(item); } @@ -360,102 +352,118 @@ public class FileViewActivity extends BaseActivity implements BottomSheetFileVie if("deleteFile".equals(text)) { - String fileExtension = FileUtils.getExtension(singleFileName); - - String data = AppUtil.getFileType(fileExtension) == AppUtil.FileType.TEXT ? - AppUtil.decodeBase64(tinyDB.getString("downloadFileContents")) : ""; - Intent intent = new Intent(ctx, CreateFileActivity.class); intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_DELETE); - intent.putExtra("filePath", singleFileName); - intent.putExtra("fileSha", fileSha); - intent.putExtra("fileContents", data); + intent.putExtra("filePath", file.getPath()); + intent.putExtra("fileSha", file.getSha()); ctx.startActivity(intent); + } if("editFile".equals(text)) { - String fileExtension = FileUtils.getExtension(singleFileName); + if(binding.contents.getContent() != null && + !binding.contents.getContent().isEmpty()) { - switch(AppUtil.getFileType(fileExtension)) { + Intent intent = new Intent(ctx, CreateFileActivity.class); - case TEXT: + intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT); + intent.putExtra("filePath", file.getPath()); + intent.putExtra("fileSha", file.getSha()); + intent.putExtra("fileContents", binding.contents.getContent()); - Intent intent = new Intent(ctx, CreateFileActivity.class); + ctx.startActivity(intent); - intent.putExtra("fileAction", CreateFileActivity.FILE_ACTION_EDIT); - intent.putExtra("filePath", singleFileName); - intent.putExtra("fileSha", fileSha); - intent.putExtra("fileContents", AppUtil.decodeBase64(tinyDB.getString("downloadFileContents"))); + } else { - ctx.startActivity(intent); - break; - default: - - Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited)); + Toasty.error(ctx, getString(R.string.fileTypeCannotBeEdited)); } } } private void requestFileDownload() { - if(!tinyDB.getString("downloadFileContents").isEmpty()) { + Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); - File outputFileName = new File(tinyDB.getString("downloadFileName")); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.putExtra(Intent.EXTRA_TITLE, file.getName()); + intent.setType("*/*"); - Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); + activityResultLauncher.launch(intent); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType("*/*"); - intent.putExtra(Intent.EXTRA_TITLE, outputFileName.getName()); - - fileDownloadActivityResultLauncher.launch(intent); - } - else { - - Toasty.warning(ctx, getString(R.string.waitLoadingDownloadFile)); - } } - ActivityResultLauncher fileDownloadActivityResultLauncher = - registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + ActivityResultLauncher activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { - if (result.getResultCode() == Activity.RESULT_OK) { + if (result.getResultCode() == Activity.RESULT_OK) { - Intent data = result.getData(); + assert result.getData() != null; - try { + try { - assert data != null; - Uri uri = data.getData(); + OutputStream outputStream = getContentResolver().openOutputStream(result.getData().getData()); - assert uri != null; - OutputStream outputStream = getContentResolver().openOutputStream(uri); + NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, ctx.getPackageName()) + .setContentTitle(getString(R.string.fileViewerNotificationTitleStarted)) + .setContentText(getString(R.string.fileViewerNotificationDescriptionStarted, file.getName())) + .setSmallIcon(R.drawable.gitnex_transparent) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setChannelId(Constants.downloadNotificationChannelId) + .setProgress(100, 0, false) + .setOngoing(true); - byte[] dataAsBytes = Base64.decode(tinyDB.getString("downloadFileContents"), 0); + int notificationId = Notifications.uniqueNotificationId(ctx); - assert outputStream != null; - outputStream.write(dataAsBytes); - outputStream.close(); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);; + notificationManager.notify(notificationId, builder.build()); - Toasty.success(ctx, getString(R.string.downloadFileSaved)); - } - catch(IOException e) { + String repoFullName = tinyDB.getString("repoFullName"); + String repoBranch = tinyDB.getString("repoBranch"); + String[] parts = repoFullName.split("/"); + String repoOwner = parts[0]; + String repoName = parts[1]; - Log.e("errorFileDownloading", Objects.requireNonNull(e.getMessage())); - } - } + Thread thread = new Thread(() -> { - }); + try { - private void initCloseListener() { + Call call = RetrofitClient + .getWebInterface(ctx) + .getFileContents(Authorization.getWeb(ctx), repoOwner, repoName, repoBranch, file.getPath()); - onClickListener = view -> { + Response response = call.execute(); - getIntent().removeExtra("singleFileName"); - finish(); - }; - } + assert response.body() != null; + + AppUtil.copyProgress(response.body().byteStream(), outputStream, file.getSize(), progress -> { + builder.setProgress(100, progress, false); + notificationManager.notify(notificationId, builder.build()); + }); + + builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFinished)) + .setContentText(getString(R.string.fileViewerNotificationDescriptionFinished, file.getName())); + + } catch(IOException ignored) { + + builder.setContentTitle(getString(R.string.fileViewerNotificationTitleFailed)) + .setContentText(getString(R.string.fileViewerNotificationDescriptionFailed, file.getName())); + + } finally { + + builder.setProgress(0,0,false) + .setOngoing(false); + + notificationManager.notify(notificationId, builder.build()); + + } + }); + + thread.start(); + + } catch(IOException ignored) {} + } + + }); } 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 b02a2740..d9c0e6d0 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -10,7 +10,6 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -61,8 +60,7 @@ import org.mian.gitnex.helpers.Version; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; -import eightbitlab.com.blurview.BlurView; -import eightbitlab.com.blurview.RenderScriptBlur; +import jp.wasabeef.picasso.transformations.BlurTransformation; import retrofit2.Call; import retrofit2.Callback; @@ -73,12 +71,10 @@ import retrofit2.Callback; public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener, BottomSheetDraftsFragment.BottomSheetListener { private DrawerLayout drawer; - private BlurView blurView; private TextView userFullName; private TextView userEmail; private ImageView userAvatar; private ImageView userAvatarBackground; - private ViewGroup navHeaderFrame; private TextView toolbarTitle; private Typeface myTypeface; @@ -273,12 +269,10 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig String userFullNameNav = tinyDB.getString("userFullname"); String userAvatarNav = tinyDB.getString("userAvatar"); - blurView = hView.findViewById(R.id.blurView); userEmail = hView.findViewById(R.id.userEmail); userFullName = hView.findViewById(R.id.userFullname); userAvatar = hView.findViewById(R.id.userAvatar); userAvatarBackground = hView.findViewById(R.id.userAvatarBackground); - navHeaderFrame = hView.findViewById(R.id.navHeaderFrame); List userAccountsList; userAccountsList = new ArrayList<>(); @@ -323,24 +317,18 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig PicassoService.getInstance(ctx).get() .load(userAvatarNav) + .transform(new BlurTransformation(ctx)) .into(userAvatarBackground, new com.squareup.picasso.Callback() { @Override public void onSuccess() { - - int textColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground); + int textColor = new ColorInverter().getImageViewContrastColor(userAvatar); userFullName.setTextColor(textColor); userEmail.setTextColor(textColor); - - blurView.setupWith(navHeaderFrame) - .setBlurAlgorithm(new RenderScriptBlur(ctx)) - .setBlurRadius(5) - .setHasFixedTransformationMatrix(false); } - @Override - public void onError(Exception e) {} + @Override public void onError(Exception e) {} }); } @@ -350,6 +338,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); navigationView.setCheckedItem(R.id.nav_profile); drawer.closeDrawers(); + }); getNotificationsCount(instanceToken); @@ -403,22 +392,21 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig switch(launchFragmentByHandler) { case "repos": - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); navigationView.setCheckedItem(R.id.nav_repositories); return; - case "org": + case "org": getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_organizations); return; - case "notification": + case "notification": getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NotificationsFragment()).commit(); navigationView.setCheckedItem(R.id.nav_notifications); return; - case "explore": + case "explore": getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreFragment()).commit(); navigationView.setCheckedItem(R.id.nav_explore); return; @@ -438,49 +426,48 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig 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: + 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: + 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: + 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: + 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: + 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: + 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: + default: toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); navigationView.setCheckedItem(R.id.nav_home); 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 7098dc4b..12b5d48a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MergePullRequestActivity.java @@ -21,7 +21,6 @@ import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; import java.util.Objects; -import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; @@ -170,12 +169,12 @@ public class MergePullRequestActivity extends BaseActivity { MergePullRequest mergePR = new MergePullRequest(Do, mergePRDT, mergeTitle); - Call call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR); + Call call = RetrofitClient.getApiInterface(ctx).mergePullRequest(Authorization.get(ctx), repoOwner, repoName, prIndex, mergePR); - call.enqueue(new Callback() { + call.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { if(response.code() == 200) { @@ -244,7 +243,7 @@ public class MergePullRequestActivity extends BaseActivity { } @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { + 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/RepoForksActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java index 6c3e6f63..f16cee4c 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoForksActivity.java @@ -27,7 +27,7 @@ import org.mian.gitnex.adapters.RepoForksAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.ActivityRepoForksBinding; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; @@ -46,7 +46,7 @@ public class RepoForksActivity extends BaseActivity { private TextView noData; private ProgressBar progressBar; private String TAG = "RepositoryForks"; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private int pageSize = 1; private RecyclerView recyclerView; @@ -90,7 +90,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; + resultLimit = Constants.resultLimitNewGiteaInstances; } recyclerView = activityRepoForksBinding.recyclerView; 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 d3e86f63..0b88f2f6 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsFileViewerActivity.java @@ -1,12 +1,8 @@ package org.mian.gitnex.activities; +import android.annotation.SuppressLint; import android.os.Bundle; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -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.databinding.ActivitySettingsFileviewerBinding; import org.mian.gitnex.helpers.Toasty; @@ -17,40 +13,29 @@ import org.mian.gitnex.helpers.Toasty; public class SettingsFileViewerActivity extends BaseActivity { - private View.OnClickListener onClickListener; - private static final String[] fileViewerSourceCodeThemesList = {"Sublime", "Arduino Light", "Github", "Far ", "Ir Black", "Android Studio"}; private static int fileViewerSourceCodeThemesSelectedChoice = 0; + @SuppressLint("DefaultLocale") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ActivitySettingsFileviewerBinding activitySettingsFileviewerBinding = ActivitySettingsFileviewerBinding.inflate(getLayoutInflater()); - setContentView(activitySettingsFileviewerBinding.getRoot()); + ActivitySettingsFileviewerBinding binding = ActivitySettingsFileviewerBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); - ImageView closeActivity = activitySettingsFileviewerBinding.close; - - initCloseListener(); - closeActivity.setOnClickListener(onClickListener); - - TextView fileViewerSourceCodeThemesSelected = activitySettingsFileviewerBinding.sourceCodeThemeSelected; // setter for fileviewer theme - LinearLayout sourceCodeThemeFrame = activitySettingsFileviewerBinding.sourceCodeThemeFrame; - SwitchMaterial pdfModeSwitch = activitySettingsFileviewerBinding.switchPdfMode; - - if(!tinyDB.getString("fileviewerSourceCodeThemeStr").isEmpty()) { - fileViewerSourceCodeThemesSelected.setText(tinyDB.getString("fileviewerSourceCodeThemeStr")); - } + binding.close.setOnClickListener(view -> finish()); if(fileViewerSourceCodeThemesSelectedChoice == 0) { fileViewerSourceCodeThemesSelectedChoice = tinyDB.getInt("fileviewerThemeId"); } - pdfModeSwitch.setChecked(tinyDB.getBoolean("enablePdfMode")); + binding.sourceCodeThemeSelected.setText(tinyDB.getString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[0])); + binding.switchPdfMode.setChecked(tinyDB.getBoolean("enablePdfMode")); - // fileviewer srouce code theme selection dialog - sourceCodeThemeFrame.setOnClickListener(view -> { + // fileviewer source code theme selection dialog + binding.sourceCodeThemeFrame.setOnClickListener(view -> { AlertDialog.Builder fvtsBuilder = new AlertDialog.Builder(SettingsFileViewerActivity.this); @@ -60,7 +45,7 @@ public class SettingsFileViewerActivity extends BaseActivity { fvtsBuilder.setSingleChoiceItems(fileViewerSourceCodeThemesList, fileViewerSourceCodeThemesSelectedChoice, (dialogInterfaceTheme, i) -> { fileViewerSourceCodeThemesSelectedChoice = i; - fileViewerSourceCodeThemesSelected.setText(fileViewerSourceCodeThemesList[i]); + binding.sourceCodeThemeSelected.setText(fileViewerSourceCodeThemesList[i]); tinyDB.putString("fileviewerSourceCodeThemeStr", fileViewerSourceCodeThemesList[i]); tinyDB.putInt("fileviewerSourceCodeThemeId", i); @@ -69,21 +54,20 @@ public class SettingsFileViewerActivity extends BaseActivity { }); - AlertDialog cfDialog = fvtsBuilder.create(); - cfDialog.show(); + AlertDialog alertDialog = fvtsBuilder.create(); + alertDialog.show(); + }); // pdf night mode switcher - pdfModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + binding.switchPdfMode.setOnCheckedChangeListener((buttonView, isChecked) -> { tinyDB.putBoolean("enablePdfMode", isChecked); tinyDB.putString("enablePdfModeInit", "yes"); Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); - }); - } - 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 index b668625b..1c378fd5 100644 --- a/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/SettingsNotificationsActivity.java @@ -8,7 +8,7 @@ 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.Constants; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.notifications.Notifications; @@ -33,7 +33,7 @@ public class SettingsNotificationsActivity extends BaseActivity { viewBinding.close.setOnClickListener(onClickListener); - viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay))); + viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay))); viewBinding.chooseColorState.setCardBackgroundColor(tinyDB.getInt("notificationsLightColor", Color.GREEN)); viewBinding.enableNotificationsMode.setChecked(tinyDB.getBoolean("notificationsEnabled", true)); @@ -52,9 +52,9 @@ public class SettingsNotificationsActivity extends BaseActivity { 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.setMinValue(Constants.minimumPollingDelay); + numberPicker.setMaxValue(Constants.maximumPollingDelay); + numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay)); numberPicker.setWrapSelectorWheel(true); AlertDialog.Builder builder = new AlertDialog.Builder(ctx); @@ -76,6 +76,7 @@ public class SettingsNotificationsActivity extends BaseActivity { builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss()); builder.setView(numberPicker); builder.create().show(); + }); // lights switcher diff --git a/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java index 5724dd44..261ec1cb 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java @@ -14,7 +14,6 @@ import androidx.recyclerview.widget.RecyclerView; import org.apache.commons.io.FileUtils; import org.gitnex.tea4j.models.Files; import org.mian.gitnex.R; -import org.mian.gitnex.helpers.Toasty; import java.util.ArrayList; import java.util.List; @@ -33,13 +32,12 @@ public class FilesAdapter extends RecyclerView.Adapter { - - Context context = v.getContext(); - - if(fileType.equals("file")) { - filesListener.onClickFile(fileName.getText().toString()); - } - else if(fileType.equals("dir")) { - filesListener.onClickDir(fileName.getText().toString()); - } - else { - Toasty.warning(context, context.getString(R.string.filesGenericError)); - } - - }); + fileName.setOnClickListener(v -> filesListener.onClickFile(file)); /*filesDropdownMenu.setOnClickListener(new View.OnClickListener() { @@ -170,25 +154,36 @@ public class FilesAdapter extends RecyclerView.Adapter class IssuesHolder extends RecyclerView.ViewHolder { - private String userLoginId; + private Issues issue; - private final TextView issueNumber; private final ImageView issueAssigneeAvatar; private final TextView issueTitle; private final TextView issueCreatedTime; @@ -114,7 +113,6 @@ public class IssuesAdapter extends RecyclerView.Adapter super(itemView); - issueNumber = itemView.findViewById(R.id.issueNumber); issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); issueTitle = itemView.findViewById(R.id.issueTitle); issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount); @@ -126,10 +124,10 @@ public class IssuesAdapter extends RecyclerView.Adapter Context context = title.getContext(); Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", issueNumber.getText()); + intent.putExtra("issueNumber", issue.getNumber()); TinyDB tinyDb = TinyDB.getInstance(context); - tinyDb.putString("issueNumber", issueNumber.getText().toString()); + tinyDb.putString("issueNumber", String.valueOf(issue.getNumber())); tinyDb.putString("issueType", "Issue"); context.startActivity(intent); @@ -140,18 +138,18 @@ public class IssuesAdapter extends RecyclerView.Adapter Context context = commentsCount.getContext(); Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", issueNumber.getText()); + intent.putExtra("issueNumber", issue.getNumber()); TinyDB tinyDb = TinyDB.getInstance(context); - tinyDb.putString("issueNumber", issueNumber.getText().toString()); + tinyDb.putString("issueNumber", String.valueOf(issue.getNumber())); tinyDb.putString("issueType", "Issue"); context.startActivity(intent); }); - issueAssigneeAvatar.setOnClickListener(loginId -> { - - Context context = loginId.getContext(); + issueAssigneeAvatar.setOnClickListener(v -> { + Context context = v.getContext(); + String userLoginId = issue.getUser().getLogin(); AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId)); }); @@ -159,40 +157,44 @@ public class IssuesAdapter extends RecyclerView.Adapter } @SuppressLint("SetTextI18n") - void bindData(Issues issuesModel) { + void bindData(Issues issue) { - final TinyDB tinyDb = TinyDB.getInstance(context); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); + TinyDB tinyDb = TinyDB.getInstance(context); + String locale = tinyDb.getString("locale"); + String timeFormat = tinyDb.getString("dateFormat"); - userLoginId = issuesModel.getUser().getLogin(); + PicassoService.getInstance(context).get() + .load(issue.getUser().getAvatar_url()) + .placeholder(R.drawable.loader_animated) + .transform(new RoundedTransformation(8, 0)) + .resize(120, 120) + .centerCrop() + .into(issueAssigneeAvatar); - PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar); + String issueNumber_ = "" + context.getResources().getString(R.string.hash) + issue.getNumber() + ""; + issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(issue.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY)); - String issueNumber_ = "" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + ""; - issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(issuesModel.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY)); - - issueNumber.setText(String.valueOf(issuesModel.getNumber())); - issueCommentsCount.setText(String.valueOf(issuesModel.getComments())); + this.issue = issue; + this.issueCommentsCount.setText(String.valueOf(issue.getComments())); switch(timeFormat) { case "pretty": { PrettyTime prettyTime = new PrettyTime(new Locale(locale)); - String createdTime = prettyTime.format(issuesModel.getCreated_at()); - issueCreatedTime.setText(createdTime); - issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context)); + String createdTime = prettyTime.format(issue.getCreated_at()); + this.issueCreatedTime.setText(createdTime); + this.issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issue.getCreated_at()), context)); break; } case "normal": { DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); - String createdTime = formatter.format(issuesModel.getCreated_at()); - issueCreatedTime.setText(createdTime); + String createdTime = formatter.format(issue.getCreated_at()); + this.issueCreatedTime.setText(createdTime); break; } case "normal1": { DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); - String createdTime = formatter.format(issuesModel.getCreated_at()); - issueCreatedTime.setText(createdTime); + String createdTime = formatter.format(issue.getCreated_at()); + this.issueCreatedTime.setText(createdTime); break; } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java index 46966259..48a28c44 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java @@ -18,8 +18,8 @@ import org.gitnex.tea4j.models.Milestones; import org.mian.gitnex.R; import org.mian.gitnex.actions.MilestoneActions; import org.mian.gitnex.helpers.ClickListener; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Markdown; -import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TinyDB; import java.text.DateFormat; @@ -41,7 +41,7 @@ public class MilestonesAdapter extends RecyclerView.Adapter dataListMain) { diff --git a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java index 60b64645..2d8ba45d 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java @@ -67,15 +67,11 @@ public class PullRequestsAdapter extends RecyclerView.Adapter { - - Context context = loginId.getContext(); + assigneeAvatar.setOnClickListener(v -> { + Context context = v.getContext(); + String userLoginId = pullRequest.getUser().getLogin(); AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId)); }); @@ -175,43 +179,32 @@ public class PullRequestsAdapter extends RecyclerView.Adapter" + context.getResources().getString(R.string.hash) + prModel.getNumber() + ""; - prTitle.setText(HtmlCompat.fromHtml(prNumber_ + " " + EmojiParser.parseToUnicode(prModel.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY)); + String prNumber_ = "" + context.getResources().getString(R.string.hash) + pullRequest.getNumber() + ""; - prNumber.setText(String.valueOf(prModel.getNumber())); - prMergeable.setText(String.valueOf(prModel.isMergeable())); - if(prModel.getHead() != null) { - prHeadBranch.setText(prModel.getHead().getRef()); - if(prModel.getHead().getRepo() != null) { - prIsFork.setText(String.valueOf(prModel.getHead().getRepo().isFork())); - prForkFullName.setText(prModel.getHead().getRepo().getFull_name()); - } - else { - // pull was done from a deleted fork - prIsFork.setText("true"); - prForkFullName.setText(context.getString(R.string.prDeletedFork)); - } - } - prCommentsCount.setText(String.valueOf(prModel.getComments())); - - prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context)); + this.prTitle.setText(HtmlCompat.fromHtml(prNumber_ + " " + EmojiParser.parseToUnicode(pullRequest.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY)); + this.prCommentsCount.setText(String.valueOf(pullRequest.getComments())); + this.prCreatedTime.setText(TimeHelper.formatTime(pullRequest.getCreated_at(), new Locale(locale), timeFormat, context)); if(timeFormat.equals("pretty")) { - prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context)); + this.prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(pullRequest.getCreated_at()), context)); } - } - } static class LoadHolder extends RecyclerView.ViewHolder { 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 a2df9de1..7a30d37c 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/SearchIssuesAdapter.java @@ -47,39 +47,35 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter { Context context = v.getContext(); Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", issueNumber.getText()); + intent.putExtra("issueNumber", issue.getNumber()); - tinyDb.putString("issueNumber", issueNumber.getText().toString()); + tinyDb.putString("issueNumber", String.valueOf(issue.getNumber())); tinyDb.putString("issueType", "Issue"); - tinyDb.putString("repoFullName", repoFullName.getText().toString()); + tinyDb.putString("repoFullName", issue.getRepository().getFull_name()); - String[] parts = repoFullName.getText().toString().split("/"); + String[] parts = issue.getRepository().getFull_name().split("/"); final String repoOwner = parts[0]; final String repoName = parts[1]; @@ -104,14 +100,13 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter { - - Context context = loginId.getContext(); + issueAssigneeAvatar.setOnClickListener(v -> { + Context context = v.getContext(); + String userLoginId = issue.getUser().getLogin(); AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId)); }); } - } @NonNull @@ -130,17 +125,19 @@ public class SearchIssuesAdapter extends RecyclerView.Adapter" + currentItem.getRepository().getFull_name() + mCtx.getResources().getString(R.string.hash) + currentItem.getNumber() + ""; - holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY)); - holder.issueNumber.setText(String.valueOf(currentItem.getNumber())); + holder.issue = currentItem; + holder.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + currentItem.getTitle(), HtmlCompat.FROM_HTML_MODE_LEGACY)); holder.issueCommentsCount.setText(String.valueOf(currentItem.getComments())); - holder.repoFullName.setText(currentItem.getRepository().getFull_name()); switch(timeFormat) { case "pretty": { 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 d7772734..9071cd5e 100644 --- a/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java +++ b/app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java @@ -18,7 +18,6 @@ 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; import retrofit2.converter.scalars.ScalarsConverterFactory; @@ -32,15 +31,12 @@ public class RetrofitClient { private static final Map apiInterfaces = new ConcurrentHashMap<>(); private static final Map webInterfaces = new ConcurrentHashMap<>(); - private static Retrofit createRetrofit(Context context, String instanceUrl) { + private static Retrofit createRetrofit(Context context, String instanceUrl, boolean cacheEnabled) { 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); +// HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); +// logging.setLevel(HttpLoggingInterceptor.Level.BODY); try { @@ -49,11 +45,17 @@ public class RetrofitClient { MemorizingTrustManager memorizingTrustManager = new MemorizingTrustManager(context); sslContext.init(null, new X509TrustManager[]{ memorizingTrustManager }, new SecureRandom()); - OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder().cache(cache) - //.addInterceptor(logging) + OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder() +// .addInterceptor(logging) .sslSocketFactory(sslContext.getSocketFactory(), memorizingTrustManager) - .hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())) - .addInterceptor(chain -> { + .hostnameVerifier(memorizingTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier())); + + if(cacheEnabled) { + + int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024; + Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize); + + okHttpClient.cache(cache).addInterceptor(chain -> { Request request = chain.request(); @@ -64,6 +66,7 @@ public class RetrofitClient { return chain.proceed(request); }); + } return new Retrofit.Builder() .baseUrl(instanceUrl) @@ -101,7 +104,7 @@ public class RetrofitClient { synchronized(RetrofitClient.class) { if(!apiInterfaces.containsKey(url)) { - ApiInterface apiInterface = createRetrofit(context, url).create(ApiInterface.class); + ApiInterface apiInterface = createRetrofit(context, url, true).create(ApiInterface.class); apiInterfaces.put(url, apiInterface); return apiInterface; @@ -119,7 +122,7 @@ public class RetrofitClient { synchronized(RetrofitClient.class) { if(!webInterfaces.containsKey(url)) { - WebInterface webInterface = createRetrofit(context, url).create(WebInterface.class); + WebInterface webInterface = createRetrofit(context, url, false).create(WebInterface.class); webInterfaces.put(url, webInterface); return webInterface; diff --git a/app/src/main/java/org/mian/gitnex/core/MainApplication.java b/app/src/main/java/org/mian/gitnex/core/MainApplication.java index ceed209a..c595d1f5 100644 --- a/app/src/main/java/org/mian/gitnex/core/MainApplication.java +++ b/app/src/main/java/org/mian/gitnex/core/MainApplication.java @@ -14,8 +14,8 @@ import org.acra.config.MailSenderConfigurationBuilder; import org.acra.data.StringFormat; import org.mian.gitnex.R; import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.FontsOverride; -import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.notifications.Notifications; @@ -28,7 +28,9 @@ import org.mian.gitnex.notifications.Notifications; resTitle = R.string.crashTitle, resChannelName = R.string.setCrashReports, resText = R.string.crashMessage) -@AcraCore(reportContent = { ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.STACK_TRACE }) +@AcraCore(reportContent = { + ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, + ReportField.STACK_TRACE, ReportField.AVAILABLE_MEM_SIZE, ReportField.BRAND }) public class MainApplication extends Application { @@ -81,6 +83,7 @@ public class MainApplication extends Application { } + Notifications.createChannels(appCtx); Notifications.startWorker(appCtx); } @@ -121,7 +124,7 @@ public class MainApplication extends Application { // setting default polling delay if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) { - tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay); + tinyDB.putInt("pollingDelayMinutes", Constants.defaultPollingDelay); } // disable biometric by default 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 fd3fd691..8a4307f0 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 @@ -7,7 +7,7 @@ import org.mian.gitnex.database.dao.DraftsDao; import org.mian.gitnex.database.db.GitnexDatabase; import org.mian.gitnex.database.models.Draft; import org.mian.gitnex.database.models.DraftWithRepository; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import java.util.List; /** @@ -51,7 +51,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsApi, e.toString()); + Log.e(Constants.draftsApi, e.toString()); } return draftId; @@ -67,7 +67,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsApi, e.toString()); + Log.e(Constants.draftsApi, e.toString()); } return draftId; @@ -83,7 +83,7 @@ public class DraftsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.draftsApi, e.toString()); + Log.e(Constants.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 55fd537c..ef5e1f5d 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 @@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData; import org.mian.gitnex.database.dao.RepositoriesDao; import org.mian.gitnex.database.db.GitnexDatabase; import org.mian.gitnex.database.models.Repository; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import java.util.List; /** @@ -47,7 +47,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); + Log.e(Constants.repositoriesApi, e.toString()); } return repositoryId; @@ -63,7 +63,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); + Log.e(Constants.repositoriesApi, e.toString()); } return repository; @@ -89,7 +89,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); + Log.e(Constants.repositoriesApi, e.toString()); } return checkRepository; @@ -105,7 +105,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); + Log.e(Constants.repositoriesApi, e.toString()); } return repository; @@ -121,7 +121,7 @@ public class RepositoriesApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.repositoriesApi, e.toString()); + Log.e(Constants.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 92e7f183..482da27b 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 @@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData; import org.mian.gitnex.database.dao.UserAccountsDao; import org.mian.gitnex.database.db.GitnexDatabase; import org.mian.gitnex.database.models.UserAccount; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import java.util.List; /** @@ -50,7 +50,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); + Log.e(Constants.userAccountsApi, e.toString()); } return accountId; @@ -81,7 +81,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); + Log.e(Constants.userAccountsApi, e.toString()); } return userAccount; @@ -97,7 +97,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); + Log.e(Constants.userAccountsApi, e.toString()); } return checkAccount; @@ -118,7 +118,7 @@ public class UserAccountsApi { } catch(InterruptedException e) { - Log.e(StaticGlobalVariables.userAccountsApi, e.toString()); + Log.e(Constants.userAccountsApi, e.toString()); } return userAccounts; diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetDraftsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetDraftsFragment.java index 5e3501f4..ef3b8048 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetDraftsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetDraftsFragment.java @@ -10,7 +10,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.mian.gitnex.databinding.BottomSheetDraftsBinding; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; /** * Author M M Arif @@ -18,7 +18,7 @@ import org.mian.gitnex.helpers.StaticGlobalVariables; public class BottomSheetDraftsFragment extends BottomSheetDialogFragment { - private String TAG = StaticGlobalVariables.tagDraftsBottomSheet; + private String TAG = Constants.tagDraftsBottomSheet; private BottomSheetDraftsFragment.BottomSheetListener bmListener; @Nullable 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 a138c8c9..df04d66e 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetReplyFragment.java @@ -25,7 +25,7 @@ import org.mian.gitnex.actions.IssueActions; import org.mian.gitnex.activities.MainActivity; import org.mian.gitnex.database.api.DraftsApi; import org.mian.gitnex.databinding.BottomSheetReplyLayoutBinding; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import java.util.Objects; @@ -266,11 +266,11 @@ public class BottomSheetReplyFragment extends BottomSheetDialogFragment { String draftType; if(tinyDB.getString("issueType").equalsIgnoreCase("Issue")) { - draftType = StaticGlobalVariables.draftTypeIssue; + draftType = Constants.draftTypeIssue; } else if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) { - draftType = StaticGlobalVariables.draftTypePull; + draftType = Constants.draftTypePull; } else { 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 db32f168..e09cbb05 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ExploreRepositoriesFragment.java @@ -28,8 +28,8 @@ import org.mian.gitnex.databinding.CustomExploreRepositoriesDialogBinding; import org.mian.gitnex.databinding.FragmentExploreRepoBinding; import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.InfiniteScrollListener; -import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; @@ -80,7 +80,7 @@ public class ExploreRepositoriesFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - limit = StaticGlobalVariables.resultLimitNewGiteaInstances; + limit = Constants.resultLimitNewGiteaInstances; } LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx); @@ -104,7 +104,7 @@ public class ExploreRepositoriesFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - limit = StaticGlobalVariables.resultLimitNewGiteaInstances; + limit = Constants.resultLimitNewGiteaInstances; } else { limit = 10; @@ -134,7 +134,7 @@ public class ExploreRepositoriesFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - limit = StaticGlobalVariables.resultLimitNewGiteaInstances; + limit = Constants.resultLimitNewGiteaInstances; } else { limit = 10; @@ -156,7 +156,7 @@ public class ExploreRepositoriesFragment extends Fragment { int apiCallDefaultLimit = 10; // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - apiCallDefaultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + apiCallDefaultLimit = Constants.resultLimitNewGiteaInstances; } if(apiCallDefaultLimit > limit) { 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 5f986962..4d381550 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java @@ -11,15 +11,12 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; -import android.widget.LinearLayout; -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 org.gitnex.tea4j.models.Files; import org.mian.gitnex.R; import org.mian.gitnex.activities.FileViewActivity; import org.mian.gitnex.activities.RepoDetailActivity; @@ -31,7 +28,6 @@ import org.mian.gitnex.helpers.Path; import org.mian.gitnex.viewmodels.FilesViewModel; import java.util.ArrayList; import java.util.Collections; -import moe.feng.common.view.breadcrumbs.BreadcrumbsView; import moe.feng.common.view.breadcrumbs.DefaultBreadcrumbsCallback; import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem; @@ -41,15 +37,11 @@ import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem; public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapterListener { - private ProgressBar mProgressBar; - private RecyclerView mRecyclerView; - private TextView noDataFiles; - private LinearLayout filesFrame; + private FragmentFilesBinding binding; private static final String repoNameF = "param2"; private static final String repoOwnerF = "param1"; private static final String repoRefF = "param3"; - private BreadcrumbsView mBreadcrumbsView; private String repoName; private String repoOwner; @@ -92,28 +84,21 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - FragmentFilesBinding fragmentFilesBinding = FragmentFilesBinding.inflate(inflater, container, false); + binding = FragmentFilesBinding.inflate(inflater, container, false); setHasOptionsMenu(true); - noDataFiles = fragmentFilesBinding.noDataFiles; - filesFrame = fragmentFilesBinding.filesFrame; - filesAdapter = new FilesAdapter(getContext(), this); - mRecyclerView = fragmentFilesBinding.recyclerView; - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - mRecyclerView.setAdapter(filesAdapter); + binding.recyclerView.setHasFixedSize(true); + binding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + binding.recyclerView.setAdapter(filesAdapter); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); - mRecyclerView.addItemDecoration(dividerItemDecoration); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(binding.recyclerView.getContext(), DividerItemDecoration.VERTICAL); + binding.recyclerView.addItemDecoration(dividerItemDecoration); - mProgressBar = fragmentFilesBinding.progressBar; - - mBreadcrumbsView = fragmentFilesBinding.breadcrumbsView; - mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); + binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); // noinspection unchecked - mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { + binding.breadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { @SuppressLint("SetTextI18n") @Override @@ -140,14 +125,14 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter path.clear(); ref = repoBranch; - mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); + binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, repoBranch); }); fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref); - return fragmentFilesBinding.getRoot(); + return binding.getRoot(); } @Override @@ -157,40 +142,35 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter } @Override - public void onClickDir(String dirName) { + public void onClickFile(Files file) { - path.add(dirName); - mBreadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(dirName))); + switch(file.getType()) { - fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref); + case "dir": + path.add(file.getName()); + binding.breadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(file.getName()))); - } + fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref); + break; - @Override - public void onClickFile(String fileName) { + case "file": + Intent intent = new Intent(getContext(), FileViewActivity.class); + intent.putExtra("file", file); - Intent intent = new Intent(getContext(), FileViewActivity.class); + requireContext().startActivity(intent); + break; - if(path.size() != 0) { - - intent.putExtra("singleFileName", path.toString() + "/" + fileName); } - else { - - intent.putExtra("singleFileName", fileName); - } - - requireContext().startActivity(intent); } private void fetchDataAsync(String instanceToken, String owner, String repo, String ref) { - mRecyclerView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); + binding.recyclerView.setVisibility(View.GONE); + binding.progressBar.setVisibility(View.VISIBLE); FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { + filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { filesAdapter.getOriginalFiles().clear(); filesAdapter.getOriginalFiles().addAll(filesListMain); @@ -198,16 +178,16 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter if(filesListMain.size() > 0) { - AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame); - noDataFiles.setVisibility(View.GONE); + AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame); + binding.noDataFiles.setVisibility(View.GONE); } else { - AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles); + AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame, binding.noDataFiles); } - filesFrame.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); + binding.filesFrame.setVisibility(View.VISIBLE); + binding.progressBar.setVisibility(View.GONE); }); @@ -215,12 +195,12 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter private void fetchDataAsyncSub(String instanceToken, String owner, String repo, String filesDir, String ref) { - mRecyclerView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); + binding.recyclerView.setVisibility(View.GONE); + binding.progressBar.setVisibility(View.VISIBLE); - FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); + FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel2.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), mProgressBar, noDataFiles).observe(this, filesListMain2 -> { + filesModel.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(this, filesListMain2 -> { filesAdapter.getOriginalFiles().clear(); filesAdapter.getOriginalFiles().addAll(filesListMain2); @@ -228,15 +208,15 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter if(filesListMain2.size() > 0) { - AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame); - noDataFiles.setVisibility(View.GONE); + AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame); + binding.noDataFiles.setVisibility(View.GONE); } else { - AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles); + AppUtil.setMultiVisibility(View.VISIBLE, binding.recyclerView, binding.filesFrame, binding.noDataFiles); } - filesFrame.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); + binding.filesFrame.setVisibility(View.VISIBLE); + binding.progressBar.setVisibility(View.GONE); }); @@ -259,7 +239,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter @Override public boolean onQueryTextChange(String newText) { - if(mRecyclerView.getAdapter() != null) { + if(binding.recyclerView.getAdapter() != null) { filesAdapter.getFilter().filter(newText); } 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 c535bb58..29c853dd 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java @@ -28,7 +28,7 @@ import org.mian.gitnex.adapters.IssuesAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.FragmentIssuesBinding; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; @@ -49,12 +49,12 @@ public class IssuesFragment extends Fragment { private List issuesList; private IssuesAdapter adapter; private Context context; - private int pageSize = StaticGlobalVariables.issuesPageInit; + private int pageSize = Constants.issuesPageInit; private ProgressBar mProgressBar; - private String TAG = StaticGlobalVariables.tagIssuesList; + private String TAG = Constants.tagIssuesList; private TextView noDataIssues; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; - private String requestType = StaticGlobalVariables.issuesRequestType; + private int resultLimit = Constants.resultLimitOldGiteaInstances; + private String requestType = Constants.issuesRequestType; private ProgressBar progressLoadMore; @Nullable @@ -78,7 +78,7 @@ public class IssuesFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } recyclerView = fragmentIssuesBinding.recyclerView; 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 f8657f11..ca4512cc 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java @@ -23,7 +23,7 @@ import org.mian.gitnex.adapters.MilestonesAdapter; 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.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Version; import java.util.ArrayList; @@ -44,9 +44,9 @@ public class MilestonesFragment extends Fragment { private List dataList; private MilestonesAdapter adapter; private Context ctx; - private int pageSize = StaticGlobalVariables.milestonesPageInit; - private String TAG = StaticGlobalVariables.tagMilestonesFragment; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int pageSize = Constants.milestonesPageInit; + private String TAG = Constants.tagMilestonesFragment; + private int resultLimit = Constants.resultLimitOldGiteaInstances; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -68,7 +68,7 @@ public class MilestonesFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } dataList = new ArrayList<>(); 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 91a5aba5..a62be27d 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/NotificationsFragment.java @@ -29,8 +29,8 @@ import org.mian.gitnex.adapters.NotificationsAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.FragmentNotificationsBinding; import org.mian.gitnex.helpers.AppUtil; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.InfiniteScrollListener; -import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import java.io.IOException; @@ -83,7 +83,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap context = getContext(); tinyDB = TinyDB.getInstance(context); - pageResultLimit = StaticGlobalVariables.getCurrentResultLimit(context); + pageResultLimit = Constants.getCurrentResultLimit(context); tinyDB.putString("notificationsFilterState", currentFilterMode); markAllAsRead = fragmentNotificationsBinding.markAllAsRead; @@ -204,7 +204,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap Call> call = RetrofitClient .getApiInterface(context) .getNotificationThreads(instanceToken, false, filter, - StaticGlobalVariables.defaultOldestTimestamp, "", + Constants.defaultOldestTimestamp, "", pageCurrentIndex, pageResultLimit); call.enqueue(new Callback>() { 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 1282c19b..663d11cf 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java @@ -30,8 +30,7 @@ import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TinyDB; import java.util.Locale; -import eightbitlab.com.blurview.BlurView; -import eightbitlab.com.blurview.RenderScriptBlur; +import jp.wasabeef.picasso.transformations.BlurTransformation; /** * Author M M Arif @@ -54,7 +53,6 @@ public class ProfileFragment extends Fragment { TinyDB tinyDb = TinyDB.getInstance(getContext()); - BlurView blurView = v.findViewById(R.id.blurView); TextView userFullName = v.findViewById(R.id.userFullName); ImageView userAvatarBackground = v.findViewById(R.id.userAvatarBackground); ImageView userAvatar = v.findViewById(R.id.userAvatar); @@ -77,10 +75,10 @@ public class ProfileFragment extends Fragment { userLanguage.setText(R.string.notSupported); } - userAvatar.setOnClickListener(loginId -> { - - AppUtil.copyToClipboard(ctx, tinyDb.getString("userLogin"), ctx.getString(R.string.copyLoginIdToClipBoard, tinyDb.getString("userLogin"))); - }); + userAvatar.setOnClickListener(loginId -> + AppUtil.copyToClipboard(ctx, + tinyDb.getString("userLogin"), + ctx.getString(R.string.copyLoginIdToClipBoard, tinyDb.getString("userLogin")))); userFullName.setText(Html.fromHtml(tinyDb.getString("userFullname"))); userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin"))); @@ -94,12 +92,12 @@ public class ProfileFragment extends Fragment { PicassoService.getInstance(ctx).get() .load(tinyDb.getString("userAvatar")) + .transform(new BlurTransformation(ctx)) .into(userAvatarBackground, new Callback() { @Override public void onSuccess() { - - int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatarBackground); + int invertedColor = new ColorInverter().getImageViewContrastColor(userAvatar); userFullName.setTextColor(invertedColor); divider.setBackgroundColor(invertedColor); @@ -107,20 +105,11 @@ public class ProfileFragment extends Fragment { userLanguage.setTextColor(invertedColor); ImageViewCompat.setImageTintList(userLanguageIcon, ColorStateList.valueOf(invertedColor)); - - blurView.setupWith(aboutFrame) - .setBlurAlgorithm(new RenderScriptBlur(ctx)) - .setBlurRadius(3) - .setHasFixedTransformationMatrix(true); - } - @Override - public void onError(Exception e) {} - + @Override public void onError(Exception e) {} }); - ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager()); ViewPager mViewPager = v.findViewById(R.id.container); @@ -181,8 +170,6 @@ public class ProfileFragment extends Fragment { @Override public Fragment getItem(int position) { - Fragment fragment = null; - switch (position) { case 0: // followers @@ -196,7 +183,7 @@ public class ProfileFragment extends Fragment { } - return fragment; + return null; } 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 793378a5..0e30006a 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java @@ -28,7 +28,7 @@ import org.mian.gitnex.adapters.PullRequestsAdapter; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.databinding.FragmentPullRequestsBinding; import org.mian.gitnex.helpers.Authorization; -import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Version; @@ -49,11 +49,11 @@ public class PullRequestsFragment extends Fragment { private RecyclerView recyclerView; private List prList; private PullRequestsAdapter adapter; - private String TAG = StaticGlobalVariables.tagPullRequestsList; + private String TAG = Constants.tagPullRequestsList; private Context context; - private int pageSize = StaticGlobalVariables.prPageInit; + private int pageSize = Constants.prPageInit; private TextView noData; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private int resultLimit = Constants.resultLimitOldGiteaInstances; private ProgressBar progressLoadMore; @Nullable @@ -77,7 +77,7 @@ public class PullRequestsFragment extends Fragment { // if gitea is 1.12 or higher use the new limit if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + resultLimit = Constants.resultLimitNewGiteaInstances; } recyclerView = fragmentPullRequestsBinding.recyclerView; 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 0a3962d8..f7c67749 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/RepoInfoFragment.java @@ -8,10 +8,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; @@ -42,36 +39,18 @@ import retrofit2.Callback; public class RepoInfoFragment extends Fragment { private Context ctx; - private ProgressBar mProgressBar; private LinearLayout pageContent; private static String repoNameF = "param2"; private static String repoOwnerF = "param1"; + private FragmentRepoInfoBinding binding; + private String repoName; private String repoOwner; - private TextView repoMetaName; - private TextView repoMetaDescription; - private TextView repoMetaStars; - private TextView repoMetaPullRequests; - private LinearLayout repoMetaPullRequestsFrame; - private TextView repoMetaForks; - private TextView repoMetaSize; - private TextView repoMetaWatchers; - private TextView repoMetaCreatedAt; - private TextView repoMetaWebsite; - private Button repoAdditionalButton; - private TextView repoFileContents; - private LinearLayout repoMetaFrame; - private ImageView repoMetaDataExpandCollapse; - private ImageView repoFilenameExpandCollapse; - private LinearLayout fileContentsFrameHeader; - private LinearLayout fileContentsFrame; private OnFragmentInteractionListener mListener; - public RepoInfoFragment() { - - } + public RepoInfoFragment() {} public static RepoInfoFragment newInstance(String param1, String param2) { RepoInfoFragment fragment = new RepoInfoFragment(); @@ -94,44 +73,18 @@ public class RepoInfoFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - FragmentRepoInfoBinding fragmentRepoInfoBinding = FragmentRepoInfoBinding.inflate(inflater, container, false); + binding = FragmentRepoInfoBinding.inflate(inflater, container, false); TinyDB tinyDb = TinyDB.getInstance(getContext()); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); + ctx = getContext(); - ctx = getActivity(); - - pageContent = fragmentRepoInfoBinding.repoInfoLayout; + pageContent = binding.repoInfoLayout; pageContent.setVisibility(View.GONE); - mProgressBar = fragmentRepoInfoBinding.progressBar; - repoMetaName = fragmentRepoInfoBinding.repoMetaName; - repoMetaDescription = fragmentRepoInfoBinding.repoMetaDescription; - repoMetaStars = fragmentRepoInfoBinding.repoMetaStars; - repoMetaPullRequests = fragmentRepoInfoBinding.repoMetaPullRequests; - repoMetaPullRequestsFrame = fragmentRepoInfoBinding.repoMetaPullRequestsFrame; - repoMetaForks = fragmentRepoInfoBinding.repoMetaForks; - repoMetaSize = fragmentRepoInfoBinding.repoMetaSize; - repoMetaWatchers = fragmentRepoInfoBinding.repoMetaWatchers; - repoMetaCreatedAt = fragmentRepoInfoBinding.repoMetaCreatedAt; - repoMetaWebsite = fragmentRepoInfoBinding.repoMetaWebsite; - repoAdditionalButton = fragmentRepoInfoBinding.repoAdditionalButton; - repoFileContents = fragmentRepoInfoBinding.repoFileContents; - repoMetaFrame = fragmentRepoInfoBinding.repoMetaFrame; - LinearLayout repoMetaFrameHeader = fragmentRepoInfoBinding.repoMetaFrameHeader; - repoMetaDataExpandCollapse = fragmentRepoInfoBinding.repoMetaDataExpandCollapse; - repoFilenameExpandCollapse = fragmentRepoInfoBinding.repoFilenameExpandCollapse; - fileContentsFrameHeader = fragmentRepoInfoBinding.fileContentsFrameHeader; - fileContentsFrame = fragmentRepoInfoBinding.fileContentsFrame; - LinearLayout repoMetaStarsFrame = fragmentRepoInfoBinding.repoMetaStarsFrame; - LinearLayout repoMetaForksFrame = fragmentRepoInfoBinding.repoMetaForksFrame; - LinearLayout repoMetaWatchersFrame = fragmentRepoInfoBinding.repoMetaWatchersFrame; + binding.repoMetaFrame.setVisibility(View.GONE); - repoMetaFrame.setVisibility(View.GONE); - - getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, locale, timeFormat); + getRepoInfo(Authorization.get(getContext()), repoOwner, repoName, tinyDb.getString("locale"), tinyDb.getString("dateFormat")); getFileContents(Authorization.get(getContext()), repoOwner, repoName, getResources().getString(R.string.defaultFilename)); if(isExpandViewVisible()) { @@ -142,27 +95,26 @@ public class RepoInfoFragment extends Fragment { toggleExpandViewMeta(); } - fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView()); + binding.fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView()); + binding.repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta()); - repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta()); - - repoMetaStarsFrame.setOnClickListener(metaStars -> { + binding.repoMetaStarsFrame.setOnClickListener(metaStars -> { Intent intent = new Intent(ctx, RepoStargazersActivity.class); intent.putExtra("repoFullNameForStars", repoOwner + "/" + repoName); ctx.startActivity(intent); }); - repoMetaWatchersFrame.setOnClickListener(metaWatchers -> { + binding.repoMetaWatchersFrame.setOnClickListener(metaWatchers -> { Intent intent = new Intent(ctx, RepoWatchersActivity.class); intent.putExtra("repoFullNameForWatchers", repoOwner + "/" + repoName); ctx.startActivity(intent); }); - repoMetaPullRequestsFrame.setOnClickListener(metaPR -> RepoDetailActivity.mViewPager.setCurrentItem(3)); + binding.repoMetaPullRequestsFrame.setOnClickListener(metaPR -> RepoDetailActivity.mViewPager.setCurrentItem(3)); - return fragmentRepoInfoBinding.getRoot(); + return binding.getRoot(); } public void onButtonPressed(Uri uri) { @@ -183,42 +135,42 @@ public class RepoInfoFragment extends Fragment { private void toggleExpandView() { - if (repoFileContents.getVisibility() == View.GONE) { - repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_up); - repoFileContents.setVisibility(View.VISIBLE); + if (binding.repoFileContents.getVisibility() == View.GONE) { + binding.repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_up); + binding.repoFileContents.setVisibility(View.VISIBLE); //Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down); - //fileContentsFrame.startAnimation(slide_down); + //binding.fileContentsFrame.startAnimation(slide_down); } else { - repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_down); - repoFileContents.setVisibility(View.GONE); + binding.repoFilenameExpandCollapse.setImageResource(R.drawable.ic_chevron_down); + binding.repoFileContents.setVisibility(View.GONE); //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up); - //fileContentsFrame.startAnimation(slide_up); + //binding.fileContentsFrame.startAnimation(slide_up); } } private boolean isExpandViewVisible() { - return repoFileContents.getVisibility() == View.VISIBLE; + return binding.repoFileContents.getVisibility() == View.VISIBLE; } private void toggleExpandViewMeta() { - if (repoMetaFrame.getVisibility() == View.GONE) { - repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_up); - repoMetaFrame.setVisibility(View.VISIBLE); + if (binding.repoMetaFrame.getVisibility() == View.GONE) { + binding.repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_up); + binding.repoMetaFrame.setVisibility(View.VISIBLE); //Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down); - //repoMetaFrame.startAnimation(slide_down); + //binding.repoMetaFrame.startAnimation(slide_down); } else { - repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_down); - repoMetaFrame.setVisibility(View.GONE); + binding.repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_chevron_down); + binding.repoMetaFrame.setVisibility(View.GONE); //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up); - //repoMetaFrame.startAnimation(slide_up); + //binding.repoMetaFrame.startAnimation(slide_up); } } private boolean isExpandViewMetaVisible() { - return repoMetaFrame.getVisibility() == View.VISIBLE; + return binding.repoMetaFrame.getVisibility() == View.VISIBLE; } private void getRepoInfo(String token, final String owner, String repo, final String locale, final String timeFormat) { @@ -243,39 +195,39 @@ public class RepoInfoFragment extends Fragment { if (response.code() == 200) { assert repoInfo != null; - repoMetaName.setText(repoInfo.getName()); + binding.repoMetaName.setText(repoInfo.getName()); if(!repoInfo.getDescription().isEmpty()) { - repoMetaDescription.setText(repoInfo.getDescription()); + binding.repoMetaDescription.setText(repoInfo.getDescription()); } else { - repoMetaDescription.setText(getString(R.string.noDataDescription)); + binding.repoMetaDescription.setText(getString(R.string.noDataDescription)); } - repoMetaStars.setText(repoInfo.getStars_count()); + binding.repoMetaStars.setText(repoInfo.getStars_count()); if(repoInfo.getOpen_pull_count() != null) { - repoMetaPullRequests.setText(repoInfo.getOpen_pull_count()); + binding.repoMetaPullRequests.setText(repoInfo.getOpen_pull_count()); } else { - repoMetaPullRequestsFrame.setVisibility(View.GONE); + binding.repoMetaPullRequestsFrame.setVisibility(View.GONE); } - repoMetaForks.setText(repoInfo.getForks_count()); - repoMetaWatchers.setText(repoInfo.getWatchers_count()); - repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) (repoInfo.getSize() * 1024))); + binding.repoMetaForks.setText(repoInfo.getForks_count()); + binding.repoMetaWatchers.setText(repoInfo.getWatchers_count()); + binding.repoMetaSize.setText(FileUtils.byteCountToDisplaySize((int) repoInfo.getSize() * 1024)); - repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx)); + binding.repoMetaCreatedAt.setText(TimeHelper.formatTime(repoInfo.getCreated_at(), new Locale(locale), timeFormat, ctx)); if(timeFormat.equals("pretty")) { - repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx)); + binding.repoMetaCreatedAt.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), ctx)); } String repoMetaUpdatedAt = TimeHelper.formatTime(repoInfo.getUpdated_at(), new Locale(locale), timeFormat, ctx); String website = (repoInfo.getWebsite().isEmpty()) ? getResources().getString(R.string.noDataWebsite) : repoInfo.getWebsite(); - repoMetaWebsite.setText(website); + binding.repoMetaWebsite.setText(website); - repoAdditionalButton.setOnClickListener(v -> { + binding.repoAdditionalButton.setOnClickListener(v -> { View view = LayoutInflater.from(ctx).inflate(R.layout.layout_repo_more_info, null); @@ -334,7 +286,7 @@ public class RepoInfoFragment extends Fragment { tinyDb.putString("repoHtmlUrl", repoInfo.getHtml_url()); - mProgressBar.setVisibility(View.GONE); + binding.progressBar.setVisibility(View.GONE); pageContent.setVisibility(View.VISIBLE); } @@ -369,39 +321,41 @@ public class RepoInfoFragment extends Fragment { if (isAdded()) { - if (response.code() == 200) { + switch(response.code()) { - new Markdown(ctx, response.body(), repoFileContents); + case 200: + new Markdown(ctx, response.body(), binding.repoFileContents); + break; - } else if (response.code() == 401) { - - AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), + case 401: + AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + break; - } else if (response.code() == 403) { + case 403: + Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + break; - Toasty.error(ctx, ctx.getString(R.string.authorizeError)); + case 404: + binding.fileContentsFrameHeader.setVisibility(View.GONE); + binding.fileContentsFrame.setVisibility(View.GONE); + break; - } else if (response.code() == 404) { - - fileContentsFrameHeader.setVisibility(View.GONE); - fileContentsFrame.setVisibility(View.GONE); - - } else { - - Toasty.error(getContext(), getString(R.string.genericError)); + default: + Toasty.error(getContext(), getString(R.string.genericError)); + break; } } - } @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/fragments/SettingsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java index 8e09ee97..c1ec2c87 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/SettingsFragment.java @@ -71,6 +71,7 @@ public class SettingsFragment extends Fragment { fragmentSettingsBinding.aboutAppFrame.setOnClickListener(aboutApp -> requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit()); return fragmentSettingsBinding.getRoot(); + } public void rateThisApp() { 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 a5fee3fd..7f29c1c5 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java +++ b/app/src/main/java/org/mian/gitnex/helpers/AppUtil.java @@ -13,15 +13,16 @@ import android.util.TypedValue; import android.view.View; import androidx.annotation.ColorInt; import androidx.core.content.pm.PackageInfoCompat; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; -import java.util.List; import java.util.Locale; import java.util.Objects; @@ -31,31 +32,38 @@ import java.util.Objects; public class AppUtil { - public enum FileType { IMAGE, DOCUMENT, TEXT, UNKNOWN } + public enum FileType { IMAGE, AUDIO, VIDEO, DOCUMENT, TEXT, EXECUTABLE, UNKNOWN } - private static final HashMap, FileType> extensions = new HashMap<>(); + private static final HashMap extensions = new HashMap<>(); // AppUtil should not be instantiated. private AppUtil() {} static { - extensions.put(Arrays.asList("jpg", "jpeg", "gif", "png", "ico"), FileType.IMAGE); - extensions.put(Arrays.asList("doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "exe", "jar", "odg", "otg", "odp", "otp", "bin", "dmg", "psd", "xcf", "pdf"), FileType.DOCUMENT); - extensions.put(Arrays.asList("txt", "md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam", "hx", "ts"), FileType.TEXT); + extensions.put(new String[]{"jpg", "jpeg", "gif", "png", "ico", "tif", "tiff", "bmp"}, FileType.IMAGE); + extensions.put(new String[]{"mp3", "wav", "opus", "flac", "wma", "aac", "m4a", "oga", "mpc", "ogg"}, FileType.AUDIO); + extensions.put(new String[]{"mp4", "mkv", "avi", "mov", "wmv", "qt", "mts", "m2ts", "webm", "flv", "ogv", "amv", "mpg", "mpeg", "mpv", "m4v", "3gp", "wmv"}, FileType.VIDEO); + extensions.put(new String[]{"doc", "docx", "ppt", "pptx", "xls", "xlsx", "xlsm", "odt", "ott", "odf", "ods", "ots", "odg", "otg", "odp", "otp", "bin", "psd", "xcf", "pdf"}, FileType.DOCUMENT); + extensions.put(new String[]{"exe", "msi", "jar", "dmg", "deb", "apk"}, FileType.EXECUTABLE); + extensions.put(new String[]{"txt", "md", "json", "java", "go", "php", "c", "cc", "cpp", "h", "cxx", "cyc", "m", "cs", "bash", "sh", "bsh", "cv", "python", "perl", "pm", "rb", "ruby", "javascript", "coffee", "rc", "rs", "rust", "basic", "clj", "css", "dart", "lisp", "erl", "hs", "lsp", "rkt", "ss", "llvm", "ll", "lua", "matlab", "pascal", "r", "scala", "sql", "latex", "tex", "vb", "vbs", "vhd", "tcl", "wiki.meta", "yaml", "yml", "markdown", "xml", "proto", "regex", "py", "pl", "js", "html", "htm", "volt", "ini", "htaccess", "conf", "gitignore", "gradle", "txt", "properties", "bat", "twig", "cvs", "cmake", "in", "info", "spec", "m4", "am", "dist", "pam", "hx", "ts", "kt", "kts"}, FileType.TEXT); + } public static FileType getFileType(String extension) { - for(List e : extensions.keySet()) { + if(extension != null && !extension.isEmpty()) { + for(String[] testExtensions : extensions.keySet()) { + for(String testExtension : testExtensions) { - if(e.contains(extension)) { - - return extensions.get(e); + if(testExtension.equalsIgnoreCase(extension)) + return extensions.get(testExtensions); + } } } return FileType.UNKNOWN; + } public static boolean hasNetworkConnection(Context context) { @@ -63,6 +71,45 @@ public class AppUtil { return NetworkStatusObserver.getInstance(context).hasNetworkConnection(); } + public static void copyProgress(InputStream inputStream, OutputStream outputStream, long totalSize, ProgressListener progressListener) throws IOException { + + byte[] buffer = new byte[4096]; + int read; + + long totalSteps = (long) Math.ceil((double) totalSize / buffer.length); + long stepsPerPercent = (long) Math.floor((double) totalSteps / 100); + + short percent = 0; + long stepCount = 0; + + progressListener.onActionStarted(); + + while((read = inputStream.read(buffer)) != -1) { + + outputStream.write(buffer, 0, read); + stepCount++; + + if(stepCount == stepsPerPercent) { + percent++; + if(percent <= 100) progressListener.onProgressChanged(percent); + stepCount = 0; + } + } + + if(percent < 100) { + progressListener.onProgressChanged((short) 100); + } + + progressListener.onActionFinished(); + } + + public interface ProgressListener { + default void onActionStarted() {} + default void onActionFinished() {} + + void onProgressChanged(short progress); + } + public static int getAppBuildNo(Context context) { try { 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 6a520d65..e97dd246 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/Authorization.java +++ b/app/src/main/java/org/mian/gitnex/helpers/Authorization.java @@ -23,4 +23,12 @@ public class Authorization { return "token " + tinyDb.getString(loginUid + "-token"); } + + public static String getWeb(Context context) { + + TinyDB tinyDb = TinyDB.getInstance(context); + return Credentials.basic("", tinyDb.getString(tinyDb.getString("loginUid") + "-token")); + + } + } diff --git a/app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java b/app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java index e1f16d79..00925b0e 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java +++ b/app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java @@ -5,6 +5,7 @@ import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.widget.ImageView; import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; /** * Author M M Arif @@ -17,45 +18,36 @@ public class ColorInverter { double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; - int d; - if (a < 0.5) { - d = 30; // almost black - } else { - d = 255; // white - } + int d = (a < 0.30) ? + 30 : // almost black + 255; // white return Color.rgb(d, d, d); } @ColorInt - public int getImageViewContrastColor(ImageView imageView) { + public int getBitmapContrastColor(@NonNull Bitmap bitmap) { - if(imageView != null) { + int colorSum = 0; + int divisionValue = 0; - Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); + for(int height=0; height= Build.VERSION_CODES.O) { + + // Delete old notification channels + notificationManager.deleteNotificationChannel(context.getPackageName()); // TODO Can be removed in future versions + + // Create new notification channels + NotificationChannel mainChannel = new NotificationChannel(Constants.mainNotificationChannelId, context.getString(R.string.mainNotificationChannelName), NotificationManager.IMPORTANCE_DEFAULT); + mainChannel.setDescription(context.getString(R.string.mainNotificationChannelDescription)); + + if(tinyDB.getBoolean("notificationsEnableVibration", true)) { + mainChannel.setVibrationPattern(new long[] { 1000, 1000 }); + mainChannel.enableVibration(true); + } else { + mainChannel.enableVibration(false); + } + + if(tinyDB.getBoolean("notificationsEnableLights", true)) { + mainChannel.setLightColor(tinyDB.getInt("notificationsLightColor", Color.GREEN)); + mainChannel.enableLights(true); + } else { + mainChannel.enableLights(false); + } + + NotificationChannel downloadChannel = new NotificationChannel(Constants.downloadNotificationChannelId, context.getString(R.string.fileViewerNotificationChannelName), NotificationManager.IMPORTANCE_LOW); + downloadChannel.setDescription(context.getString(R.string.fileViewerNotificationChannelDescription)); + + notificationManager.createNotificationChannel(mainChannel); + notificationManager.createNotificationChannel(downloadChannel); - notificationsSupported = new Version(currentVersion).higherOrEqual("1.12.3") ? 1 : 0; } } @@ -56,7 +99,7 @@ public class Notifications { constraints.setRequiresDeviceIdle(false); } - int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay), 15); + int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay), 15); PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, pollingDelayMinutes, TimeUnit.MINUTES) .setConstraints(constraints.build()) @@ -68,4 +111,15 @@ public class Notifications { } } } + + private static void checkVersion(TinyDB tinyDB) { + + String currentVersion = tinyDB.getString("giteaVersion"); + + if(tinyDB.getBoolean("loggedInMode") && !currentVersion.isEmpty()) { + + notificationsSupported = new Version(currentVersion).higherOrEqual("1.12.3") ? 1 : 0; + } + } + } 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 1972f016..cdf40405 100644 --- a/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java +++ b/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java @@ -1,15 +1,11 @@ package org.mian.gitnex.notifications; import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.RingtoneManager; -import android.os.Build; -import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; @@ -20,7 +16,8 @@ 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.Authorization; +import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.TinyDB; import java.util.Date; import java.util.List; @@ -34,7 +31,6 @@ import retrofit2.Response; public class NotificationsWorker extends Worker { private static final int MAXIMUM_NOTIFICATIONS = 100; - private static final long[] VIBRATION_PATTERN = new long[]{ 1000, 1000 }; private final Context context; private final TinyDB tinyDB; @@ -45,17 +41,16 @@ public class NotificationsWorker extends Worker { this.context = context; this.tinyDB = TinyDB.getInstance(context); + } @NonNull @Override public Result doWork() { - String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token"); + int notificationLoops = tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay) >= 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 .getApiInterface(context) - .getNotificationThreads(token, false, new String[]{"unread"}, previousRefreshTimestamp, + .getNotificationThreads(Authorization.get(context), false, new String[]{"unread"}, previousRefreshTimestamp, null, 1, MAXIMUM_NOTIFICATIONS); Response> response = call.execute(); @@ -76,34 +71,24 @@ public class NotificationsWorker extends Worker { List notificationThreads = response.body(); - if(!notificationThreads.isEmpty()) { - + if(!notificationThreads.isEmpty()) sendNotification(notificationThreads); - } tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date())); } - else { - Log.e("onError", String.valueOf(response.code())); - } - } - catch(Exception e) { - - Log.e("onError", e.toString()); - } + } catch(Exception ignored) {} try { - if(notificationLoops > 1 && i < (notificationLoops - 1)) { Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime)); } - } - catch (InterruptedException ignored) {} + } catch (InterruptedException ignored) {} } return Result.success(); + } private void sendNotification(List notificationThreads) { @@ -112,7 +97,6 @@ public class NotificationsWorker extends Worker { PendingIntent pendingIntent = getPendingIntent(); NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context); - attachNotificationChannel(notificationManagerCompat); Notification summaryNotification = new NotificationCompat.Builder(context, context.getPackageName()) .setContentTitle(context.getString(R.string.newMessages)) @@ -122,15 +106,13 @@ public class NotificationsWorker extends Worker { .setGroupSummary(true) .setAutoCancel(true) .setContentIntent(pendingIntent) + .setChannelId(Constants.mainNotificationChannelId) .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()); @@ -140,49 +122,8 @@ public class NotificationsWorker extends Worker { .setGroup(context.getPackageName()) .setContentIntent(pendingIntent); - pushNotification(notificationManagerCompat1, builder1.build()); - } - } + notificationManagerCompat.notify(Notifications.uniqueNotificationId(context), 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.appName), - 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); } } @@ -193,6 +134,7 @@ public class NotificationsWorker extends Worker { .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setChannelId(Constants.mainNotificationChannelId) .setAutoCancel(true); if(tinyDB.getBoolean("notificationsEnableLights", true)) { @@ -201,11 +143,8 @@ public class NotificationsWorker extends Worker { } if(tinyDB.getBoolean("notificationsEnableVibration", true)) { - - builder.setVibrate(VIBRATION_PATTERN); - } - else { - + builder.setVibrate(new long[]{ 1000, 1000 }); + } else { builder.setVibrate(null); } @@ -219,5 +158,6 @@ public class NotificationsWorker extends Worker { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); return PendingIntent.getActivity(context, 0, intent, 0); + } } diff --git a/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java b/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java index a263f338..1e074180 100644 --- a/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java +++ b/app/src/main/java/org/mian/gitnex/views/ReactionSpinner.java @@ -18,6 +18,7 @@ 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.Constants; import org.mian.gitnex.helpers.TinyDB; import java.io.IOException; import java.util.ArrayList; @@ -222,7 +223,7 @@ public class ReactionSpinner extends HorizontalScrollView { 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")); + allowedReactions.addAll(Arrays.asList(Constants.fallbackReactions)); } return allowedReactions; diff --git a/app/src/main/res/drawable/ic_directory.xml b/app/src/main/res/drawable/ic_directory.xml index 3165bd97..0756ffd6 100644 --- a/app/src/main/res/drawable/ic_directory.xml +++ b/app/src/main/res/drawable/ic_directory.xml @@ -4,10 +4,7 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="?attr/iconsColor" + android:pathData="M3.75,4.5a0.25,0.25 0,0 0,-0.25 0.25v14.5c0,0.138 0.112,0.25 0.25,0.25h16.5a0.25,0.25 0,0 0,0.25 -0.25V7.687a0.25,0.25 0,0 0,-0.25 -0.25h-8.471a1.75,1.75 0,0 1,-1.447 -0.765L8.928,4.61a0.25,0.25 0,0 0,-0.208 -0.11H3.75zM2,4.75C2,3.784 2.784,3 3.75,3h4.971c0.58,0 1.12,0.286 1.447,0.765l1.404,2.063a0.25,0.25 0,0 0,0.207 0.11h8.471c0.966,0 1.75,0.783 1.75,1.75V19.25A1.75,1.75 0,0 1,20.25 21H3.75A1.75,1.75 0,0 1,2 19.25V4.75z" + android:fillType="evenOdd"/> diff --git a/app/src/main/res/drawable/ic_file.xml b/app/src/main/res/drawable/ic_file.xml index 45577def..b2c86a3c 100644 --- a/app/src/main/res/drawable/ic_file.xml +++ b/app/src/main/res/drawable/ic_file.xml @@ -4,17 +4,7 @@ android:viewportWidth="24" android:viewportHeight="24"> - + android:fillColor="?attr/iconsColor" + android:pathData="M5,2.5a0.5,0.5 0,0 0,-0.5 0.5v18a0.5,0.5 0,0 0,0.5 0.5h14a0.5,0.5 0,0 0,0.5 -0.5L19.5,8.5h-4a2,2 0,0 1,-2 -2v-4L5,2.5zM15,2.5v4a0.5,0.5 0,0 0,0.5 0.5h4a0.5,0.5 0,0 0,-0.146 -0.336l-4.018,-4.018A0.5,0.5 0,0 0,15 2.5zM3,3a2,2 0,0 1,2 -2h9.982a2,2 0,0 1,1.414 0.586l4.018,4.018A2,2 0,0 1,21 7.018L21,21a2,2 0,0 1,-2 2L5,23a2,2 0,0 1,-2 -2L3,3z" + android:fillType="evenOdd"/> diff --git a/app/src/main/res/drawable/ic_question.xml b/app/src/main/res/drawable/ic_question.xml index cbe0237d..ca41c5a6 100644 --- a/app/src/main/res/drawable/ic_question.xml +++ b/app/src/main/res/drawable/ic_question.xml @@ -4,24 +4,10 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="?attr/iconsColor" + android:pathData="M10.97,8.265a1.45,1.45 0,0 0,-0.487 0.57,0.75 0.75,0 0,1 -1.341,-0.67c0.2,-0.402 0.513,-0.826 0.997,-1.148C10.627,6.69 11.244,6.5 12,6.5c0.658,0 1.369,0.195 1.934,0.619a2.45,2.45 0,0 1,1.004 2.006c0,1.033 -0.513,1.72 -1.027,2.215 -0.19,0.183 -0.399,0.358 -0.579,0.508l-0.147,0.123a4.329,4.329 0,0 0,-0.435 0.409v1.37a0.75,0.75 0,1 1,-1.5 0v-1.473c0,-0.237 0.067,-0.504 0.247,-0.736 0.22,-0.28 0.486,-0.517 0.718,-0.714l0.183,-0.153 0.001,-0.001c0.172,-0.143 0.324,-0.27 0.47,-0.412 0.368,-0.355 0.569,-0.676 0.569,-1.136a0.953,0.953 0,0 0,-0.404 -0.806C12.766,8.118 12.384,8 12,8c-0.494,0 -0.814,0.121 -1.03,0.265zM13,17a1,1 0,1 1,-2 0,1 1,0 0,1 2,0z"/> - + android:fillColor="?attr/iconsColor" + android:pathData="M12,1C5.925,1 1,5.925 1,12s4.925,11 11,11 11,-4.925 11,-11S18.075,1 12,1zM2.5,12a9.5,9.5 0,1 1,19 0,9.5 9.5,0 0,1 -19,0z" + android:fillType="evenOdd"/> diff --git a/app/src/main/res/drawable/ic_submodule.xml b/app/src/main/res/drawable/ic_submodule.xml new file mode 100644 index 00000000..2f2eb4cd --- /dev/null +++ b/app/src/main/res/drawable/ic_submodule.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_symlink.xml b/app/src/main/res/drawable/ic_symlink.xml new file mode 100644 index 00000000..9a363867 --- /dev/null +++ b/app/src/main/res/drawable/ic_symlink.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_file_view.xml b/app/src/main/res/layout/activity_file_view.xml index 57e080b2..022e08c4 100644 --- a/app/src/main/res/layout/activity_file_view.xml +++ b/app/src/main/res/layout/activity_file_view.xml @@ -64,20 +64,21 @@ android:orientation="vertical"> + android:visibility="gone"> - + @@ -86,7 +87,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/primaryBackgroundColor" - android:orientation="vertical"> + android:orientation="vertical" + android:visibility="gone"> diff --git a/app/src/main/res/layout/fragment_files.xml b/app/src/main/res/layout/fragment_files.xml index ed740290..e3cc0fd1 100644 --- a/app/src/main/res/layout/fragment_files.xml +++ b/app/src/main/res/layout/fragment_files.xml @@ -46,10 +46,11 @@ diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml index 5be95c23..919ccfb2 100644 --- a/app/src/main/res/layout/fragment_profile.xml +++ b/app/src/main/res/layout/fragment_profile.xml @@ -21,80 +21,72 @@ android:contentDescription="@string/generalImgContentText" android:scaleType="centerCrop" /> - + android:gravity="center" + android:orientation="vertical" + android:padding="16dp"> + + + + + + + + + + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical"> + android:src="@drawable/ic_language" + app:tint="@color/colorWhite" /> - - - - - - - - - - - - - - + diff --git a/app/src/main/res/layout/layout_last_commit.xml b/app/src/main/res/layout/layout_last_commit.xml new file mode 100644 index 00000000..e85bf061 --- /dev/null +++ b/app/src/main/res/layout/layout_last_commit.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_issues.xml b/app/src/main/res/layout/list_issues.xml index 8d4faff7..09dfead1 100644 --- a/app/src/main/res/layout/list_issues.xml +++ b/app/src/main/res/layout/list_issues.xml @@ -4,102 +4,83 @@ android:id="@+id/relativeLayoutFrameIssuesList" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_margin="15dp" + android:orientation="vertical" android:background="?attr/primaryBackgroundColor"> - + - - - - - + android:layout_marginBottom="10dp" + android:orientation="horizontal"> + + + + + + - - - - - - - - - - - - + + - + diff --git a/app/src/main/res/layout/list_pr.xml b/app/src/main/res/layout/list_pr.xml index a62e94a6..a7f49b8d 100644 --- a/app/src/main/res/layout/list_pr.xml +++ b/app/src/main/res/layout/list_pr.xml @@ -5,119 +5,82 @@ android:id="@+id/relativeLayoutFrame" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_margin="15dp" + android:orientation="vertical" android:background="?attr/primaryBackgroundColor"> - + - - - - - - - - - - - + android:layout_marginBottom="10dp" + android:orientation="horizontal"> - - - - - - - - - - - - - - - - - + android:gravity="top|center_vertical" + android:textAlignment="gravity" + android:textColor="?attr/primaryTextColor" + android:textSize="18sp" /> - + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/nav_header.xml b/app/src/main/res/layout/nav_header.xml index 438a55d7..c607d16a 100644 --- a/app/src/main/res/layout/nav_header.xml +++ b/app/src/main/res/layout/nav_header.xml @@ -1,6 +1,7 @@ @@ -10,106 +11,79 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:contentDescription="@string/generalImgContentText" - android:scaleType="centerCrop" /> + android:scaleType="centerCrop" + tools:srcCompat="@tools:sample/backgrounds/scenic" /> - + android:gravity="bottom" + android:orientation="vertical" + android:paddingStart="20dp" + android:paddingTop="20dp" + android:paddingEnd="20dp" + android:paddingBottom="20dp"> + android:layout_height="wrap_content" + android:orientation="horizontal"> - - - - - - - - - - - - - + + - - - - - - - - - - - - + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + app:reverseLayout="true" /> - + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41bc002c..a3efcf1e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -578,7 +578,7 @@ Download This File Please wait for the file to load to memory File saved successfully - This file type is not supported in file viewer. Download it instead from the three dotted menu? + This file type/size is not supported in file viewer. You can download it from the menu. Delete This File Edit This File Delete %1$s @@ -674,7 +674,8 @@ Choose Color New messages You\'ve got %d new notifications. - This is the main notification channel of GitNex. + Notifications + This is the main notification channel of GitNex. - %s (%s) Read @@ -742,4 +743,15 @@ Login ID \'%s\' copied to clipboard + + Download in progress + Downloading %s + Download successful + Downloaded %s + Download failed + Couldn\'t download %s + + Download manager + Indicates the progress of ongoing downloads + diff --git a/build.gradle b/build.gradle index 6bdfda9e..cec44c6f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:4.1.3' } }