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' } }