diff --git a/.gitignore b/.gitignore
index 7f5d55f5..a12bd4eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
# Release dir
app/release/*
+app/free/*
# Pro dir
app/pro/*
diff --git a/README.md b/README.md
index 79146187..f664148c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[![License: GPL v3](https://codeberg.org/gitnex/GitNex/raw/branch/main/assets/license.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Pipeline status](https://ci.codeberg.org/api/badges/gitnex/GitNex/status.svg)](https://ci.codeberg.org/gitnex/GitNex) [![Release](https://img.shields.io/badge/dynamic/json.svg?label=release&url=https://codeberg.org/api/v1/repos/gitnex/GitNex/releases&query=$[0].tag_name)](https://codeberg.org/gitnex/GitNex/releases) [![Crowdin](https://badges.crowdin.net/gitnex/localized.svg)](https://crowdin.com/project/gitnex) [![Join the Discord chat at https://discord.gg/FbSS4rf](https://img.shields.io/discord/632219664587685908.svg)](https://discord.gg/FbSS4rf)
-[](https://www.patreon.com/mmarif) [](https://www.buymeacoffee.com/mmarif)
+[](https://www.patreon.com/mmarif)
# GitNex - Android client for Forgejo and Gitea
diff --git a/app/build.gradle b/app/build.gradle
index 405f8ae2..2c12496a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id "com.diffplug.spotless" version "6.11.0"
+ id "com.diffplug.spotless" version "6.25.0"
}
apply plugin: 'com.android.application'
@@ -8,8 +8,8 @@ android {
applicationId "org.mian.gitnex"
minSdkVersion 23
targetSdkVersion 34
- versionCode 550
- versionName "5.5.0"
+ versionCode 595
+ versionName "6.0.0-dev"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileSdk 34
@@ -56,25 +56,25 @@ configurations {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
- implementation 'androidx.compose.material3:material3:1.2.1'
- implementation 'androidx.compose.material3:material3-window-size-class:1.2.1'
+ implementation 'androidx.compose.material3:material3:1.3.0'
+ implementation 'androidx.compose.material3:material3-window-size-class:1.3.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.7.0"
testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'androidx.test.ext:junit:1.1.5'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
- implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.12'
- implementation 'com.google.code.gson:gson:2.10.1'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+ implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.14'
+ implementation 'com.google.code.gson:gson:2.11.0'
implementation "com.squareup.picasso:picasso:2.71828"
implementation 'com.github.ramseth001:TextDrawable:1.1.3'
implementation 'com.squareup.retrofit2:retrofit:2.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.11.0'
- implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.12'
+ implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.14'
implementation 'org.ocpsoft.prettytime:prettytime:5.0.7.Final'
implementation "com.github.skydoves:colorpickerview:2.3.0"
implementation "io.noties.markwon:core:4.6.2"
@@ -89,8 +89,7 @@ dependencies {
implementation "io.noties.markwon:recycler:4.6.2"
implementation "io.noties.markwon:recycler-table:4.6.2"
implementation "io.noties.markwon:simple-ext:4.6.2"
- implementation 'com.google.guava:guava:32.1.2-jre'
- implementation "io.noties.markwon:image-picasso:4.6.2"
+ implementation 'com.google.guava:guava:32.1.3-jre'
implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9"
//noinspection GradleDependency
implementation 'commons-io:commons-io:2.5'
@@ -101,7 +100,7 @@ dependencies {
implementation 'ch.acra:acra-notification:5.11.3'
implementation 'androidx.room:room-runtime:2.6.1'
annotationProcessor 'androidx.room:room-compiler:2.6.1'
- implementation "androidx.work:work-runtime:2.9.0"
+ implementation "androidx.work:work-runtime:2.9.1"
implementation "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
//noinspection GradleDependency
diff --git a/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java b/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java
index 517315f0..93a201a3 100644
--- a/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.biometric.BiometricManager;
import java.util.Locale;
import org.mian.gitnex.R;
import org.mian.gitnex.core.MainApplication;
@@ -118,15 +119,20 @@ public abstract class BaseActivity extends AppCompatActivity {
public void onResume() {
super.onResume();
- if (Boolean.parseBoolean(
- AppDatabaseSettings.getSettingsValue(
- ctx, AppDatabaseSettings.APP_BIOMETRIC_KEY))
- && !Boolean.parseBoolean(
- AppDatabaseSettings.getSettingsValue(
- ctx, AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY))) {
+ if (BiometricManager.from(ctx)
+ .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ == BiometricManager.BIOMETRIC_SUCCESS) {
- Intent unlockIntent = new Intent(ctx, BiometricUnlock.class);
- ctx.startActivity(unlockIntent);
+ if (Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ ctx, AppDatabaseSettings.APP_BIOMETRIC_KEY))
+ && !Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ ctx, AppDatabaseSettings.APP_BIOMETRIC_LIFE_CYCLE_KEY))) {
+
+ Intent unlockIntent = new Intent(ctx, BiometricUnlock.class);
+ ctx.startActivity(unlockIntent);
+ }
}
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/BiometricUnlock.java b/app/src/main/java/org/mian/gitnex/activities/BiometricUnlock.java
index e9ad0873..a268581f 100644
--- a/app/src/main/java/org/mian/gitnex/activities/BiometricUnlock.java
+++ b/app/src/main/java/org/mian/gitnex/activities/BiometricUnlock.java
@@ -45,7 +45,7 @@ public class BiometricUnlock extends AppCompatActivity {
super.onAuthenticationError(errorCode, errString);
- // Authentication error, close the app
+ MainActivity.closeActivity = true;
finish();
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
index 6cebaf0c..56780b9d 100644
--- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
@@ -507,6 +507,8 @@ public class CreateIssueActivity extends BaseActivity
String newIssueTitleForm,
String newIssueDueDateForm) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
+
ArrayList labelIds = new ArrayList<>();
for (Integer i : labelsIds) {
labelIds.add((long) i);
@@ -562,9 +564,11 @@ public class CreateIssueActivity extends BaseActivity
} else if (response2.code() == 401) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(true);
AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(true);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
@@ -575,6 +579,7 @@ public class CreateIssueActivity extends BaseActivity
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(true);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
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 05ad2a65..edfa0dd5 100644
--- a/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/CreatePullRequestActivity.java
@@ -414,6 +414,8 @@ public class CreatePullRequestActivity extends BaseActivity
List assignees,
String prDueDate) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
+
ArrayList labelIds = new ArrayList<>();
for (Integer i : labelsIds) {
labelIds.add((long) i);
@@ -470,18 +472,21 @@ public class CreatePullRequestActivity extends BaseActivity
} else if (response.code() == 409
|| response.message().equals("Conflict")) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.prAlreadyExists));
} else if (response.code() == 404) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
@@ -492,6 +497,7 @@ public class CreatePullRequestActivity extends BaseActivity
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ viewBinding.topAppBar.getMenu().getItem(2).setVisible(false);
SnackBar.error(
ctx,
findViewById(android.R.id.content),
diff --git a/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java
index 5d0122ad..3eeee5d9 100644
--- a/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/DeepLinksActivity.java
@@ -119,10 +119,9 @@ public class DeepLinksActivity extends BaseActivity {
finish();
} else if (Objects.equals(
data.getLastPathSegment(),
- getAccount().getAccount().getUserName())) { // your user profile
- mainIntent.putExtra("launchFragmentByLinkHandler", "profile");
- ctx.startActivity(mainIntent);
- finish();
+ getAccount().getAccount().getUserName())) { // user profile
+ new Handler(Looper.getMainLooper())
+ .postDelayed(() -> getUserOrOrg(data.getLastPathSegment()), 500);
} else if (Objects.equals(data.getLastPathSegment(), "admin")) {
mainIntent.putExtra("launchFragmentByLinkHandler", "admin");
ctx.startActivity(mainIntent);
@@ -577,7 +576,9 @@ public class DeepLinksActivity extends BaseActivity {
public void onResponse(
@NonNull Call call,
@NonNull Response response) {
- if (response.code() == 404) { // org doesn't exist or it's a user user
+ if (response.code() == 404
+ || response.code()
+ == 504) { // org doesn't exist or it's a user user
Log.d("getUserOrOrg-404", String.valueOf(response.code()));
getUser(userOrgName);
} else if (response.code() == 200) { // org
diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
index 60070604..f9685865 100644
--- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
@@ -373,8 +373,6 @@ public class IssueDetailActivity extends BaseActivity
.setSoftInputMode(
WindowManager.LayoutParams
.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
- viewBinding.commentReply.setSelection(
- viewBinding.commentReply.length());
viewBinding.send.setAlpha(buttonAlphaStatEnabled);
viewBinding.send.setEnabled(true);
} else {
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 cf41006e..e326d51b 100644
--- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
@@ -60,7 +60,6 @@ import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ChangeLog;
-import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.structs.BottomSheetListener;
import org.mian.gitnex.structs.FragmentRefreshListener;
@@ -87,6 +86,7 @@ public class MainActivity extends BaseActivity
private BottomSheetListener profileInitListener;
private FragmentRefreshListener fragmentRefreshListenerMyIssues;
private String username;
+ public static boolean closeActivity = false;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -168,11 +168,11 @@ public class MainActivity extends BaseActivity
Menu menu = navigationView.getMenu();
navNotifications = menu.findItem(R.id.nav_notifications);
- MenuItem navDashboard = menu.findItem(R.id.nav_dashboard);
+ /*MenuItem navDashboard = menu.findItem(R.id.nav_dashboard);
navDashboard.getActionView().findViewById(R.id.betaBadge).setVisibility(View.VISIBLE);
TextView dashboardBetaView = navDashboard.getActionView().findViewById(R.id.betaBadge);
- dashboardBetaView.setText(R.string.beta);
+ dashboardBetaView.setText(R.string.beta);*/
navigationView
.getViewTreeObserver()
@@ -250,8 +250,16 @@ public class MainActivity extends BaseActivity
String userFullNameNav = getAccount().getFullName();
String userAvatarNav = getAccount().getUserInfo().getAvatarUrl();
- if (!userEmailNav.isEmpty()) {
- userEmail.setText(userEmailNav);
+ if (Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ ctx,
+ AppDatabaseSettings.APP_USER_HIDE_EMAIL_IN_NAV_KEY))) {
+ userEmail.setVisibility(View.GONE);
+ } else {
+ userEmail.setVisibility(View.VISIBLE);
+ if (!userEmailNav.isEmpty()) {
+ userEmail.setText(userEmailNav);
+ }
}
if (!userFullNameNav.isEmpty()) {
@@ -260,13 +268,10 @@ public class MainActivity extends BaseActivity
if (!userAvatarNav.isEmpty()) {
- int avatarRadius = AppUtil.getPixelsFromDensity(ctx, 60);
-
PicassoService.getInstance(ctx)
.get()
.load(userAvatarNav)
.placeholder(R.drawable.loader_animated)
- .transform(new RoundedTransformation(avatarRadius, 0))
.resize(160, 160)
.centerCrop()
.into(userAvatar);
@@ -582,6 +587,11 @@ public class MainActivity extends BaseActivity
public void onResume() {
super.onResume();
+ if (closeActivity) {
+ finishAndRemoveTask();
+ closeActivity = false;
+ }
+
if (refActivity) {
this.recreate();
this.overridePendingTransition(0, 0);
diff --git a/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java b/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java
index 8e69354c..f0ef2cb4 100644
--- a/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java
@@ -126,7 +126,7 @@ public class ProfileActivity extends BaseActivity implements BottomSheetListener
RetrofitClient.getApiInterface(this)
.userCurrentCheckFollowing(username)
.enqueue(
- new Callback() {
+ new Callback<>() {
@Override
public void onResponse(
diff --git a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java
index f8f9a619..d038141d 100644
--- a/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/SettingsAppearanceActivity.java
@@ -141,6 +141,53 @@ public class SettingsAppearanceActivity extends BaseActivity {
activitySettingsAppearanceBinding.switchCounterBadge.setChecked(
!activitySettingsAppearanceBinding.switchCounterBadge.isChecked()));
+ // hide email and language in user profile screen switcher
+ activitySettingsAppearanceBinding.switchHideEmailLangInProfile.setChecked(
+ Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ ctx,
+ AppDatabaseSettings.APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY)));
+
+ activitySettingsAppearanceBinding.switchHideEmailLangInProfile.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> {
+ AppDatabaseSettings.updateSettingsValue(
+ ctx,
+ String.valueOf(isChecked),
+ AppDatabaseSettings.APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY);
+ SnackBar.success(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.settingsSave));
+ });
+ activitySettingsAppearanceBinding.hideEmailLangInProfileFrame.setOnClickListener(
+ v ->
+ activitySettingsAppearanceBinding.switchHideEmailLangInProfile.setChecked(
+ !activitySettingsAppearanceBinding.switchHideEmailLangInProfile
+ .isChecked()));
+
+ // hide email in app navigation drawer switcher
+ activitySettingsAppearanceBinding.switchHideEmailNavDrawer.setChecked(
+ Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ ctx, AppDatabaseSettings.APP_USER_HIDE_EMAIL_IN_NAV_KEY)));
+
+ activitySettingsAppearanceBinding.switchHideEmailNavDrawer.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> {
+ AppDatabaseSettings.updateSettingsValue(
+ ctx,
+ String.valueOf(isChecked),
+ AppDatabaseSettings.APP_USER_HIDE_EMAIL_IN_NAV_KEY);
+ SnackBar.success(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.settingsSave));
+ });
+ activitySettingsAppearanceBinding.hideEmailNavDrawerFrame.setOnClickListener(
+ v ->
+ activitySettingsAppearanceBinding.switchHideEmailNavDrawer.setChecked(
+ !activitySettingsAppearanceBinding.switchHideEmailNavDrawer
+ .isChecked()));
+
// show labels in lists(issues, pr) - default is color dots
activitySettingsAppearanceBinding.switchLabelsInListBadge.setChecked(
Boolean.parseBoolean(
diff --git a/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java
index cfef85c4..d17eda2f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/AdminCronTasksAdapter.java
@@ -29,7 +29,7 @@ public class AdminCronTasksAdapter
private final List tasksList;
- static class CronTasksViewHolder extends RecyclerView.ViewHolder {
+ public static class CronTasksViewHolder extends RecyclerView.ViewHolder {
private Cron cronTasks;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
index a4c2ff77..a13ebc64 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
@@ -181,7 +181,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter data);
}
- static class AssigneesViewHolder extends RecyclerView.ViewHolder {
+ public static class AssigneesViewHolder extends RecyclerView.ViewHolder {
private final CheckBox assigneesSelection;
private final TextView assigneesName;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorSearchAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorSearchAdapter.java
index a0f1d91a..5f7b205f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorSearchAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorSearchAdapter.java
@@ -64,7 +64,7 @@ public class CollaboratorSearchAdapter
int imgRadius = AppUtil.getPixelsFromDensity(context, 60);
holder.userInfo = currentItem;
- if (!currentItem.getFullName().equals("")) {
+ if (!currentItem.getFullName().isEmpty()) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullName()));
} else {
@@ -77,7 +77,7 @@ public class CollaboratorSearchAdapter
holder.userName.setText(
context.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
- if (!currentItem.getAvatarUrl().equals("")) {
+ if (!currentItem.getAvatarUrl().isEmpty()) {
PicassoService.getInstance(context)
.get()
.load(currentItem.getAvatarUrl())
@@ -140,7 +140,7 @@ public class CollaboratorSearchAdapter
return usersSearchList.size();
}
- class CollaboratorSearchViewHolder extends RecyclerView.ViewHolder {
+ public class CollaboratorSearchViewHolder extends RecyclerView.ViewHolder {
private final ImageView userAvatar;
private final TextView userFullName;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
index d39349b8..20577147 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
@@ -83,7 +83,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
viewHolder.userLoginId = currentItem.getLogin();
- if (!currentItem.getFullName().equals("")) {
+ if (!currentItem.getFullName().isEmpty()) {
viewHolder.collaboratorName.setText(Html.fromHtml(currentItem.getFullName()));
viewHolder.userName.setText(
diff --git a/app/src/main/java/org/mian/gitnex/adapters/CommitStatusesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/CommitStatusesAdapter.java
index fedd2910..c3e22a2d 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/CommitStatusesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/CommitStatusesAdapter.java
@@ -24,7 +24,7 @@ public class CommitStatusesAdapter
private final List statuses;
- static class CommitStatusesViewHolder extends RecyclerView.ViewHolder {
+ public static class CommitStatusesViewHolder extends RecyclerView.ViewHolder {
private CommitStatus status;
@@ -44,7 +44,7 @@ public class CommitStatusesAdapter
}
private void openUrl() {
- if (status.getTargetUrl() != null && !status.getTargetUrl().equals("")) {
+ if (status.getTargetUrl() != null && !status.getTargetUrl().isEmpty()) {
AppUtil.openUrlInBrowser(itemView.getContext(), status.getTargetUrl());
} else {
Toasty.info(
diff --git a/app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java
index e38b6c0d..76e7ccd7 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java
@@ -147,7 +147,7 @@ public class DiffAdapter extends BaseAdapter {
private int getLineColor(String line) {
- if (line.length() == 0) {
+ if (line.isEmpty()) {
return COLOR_NORMAL;
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
index ebb8534d..4d1e4752 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/DraftsAdapter.java
@@ -113,7 +113,7 @@ public class DraftsAdapter extends RecyclerView.Adapter list) {
currentLabelsIds = list;
@@ -116,7 +118,7 @@ public class LabelsListAdapter extends RecyclerView.Adapter data);
}
- static class LabelsViewHolder extends RecyclerView.ViewHolder {
+ public static class LabelsViewHolder extends RecyclerView.ViewHolder {
private final CheckBox labelSelection;
private final TextView labelText;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/MostVisitedReposAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MostVisitedReposAdapter.java
index 7448c1bd..ad930d6a 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/MostVisitedReposAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/MostVisitedReposAdapter.java
@@ -34,7 +34,7 @@ public class MostVisitedReposAdapter
private List mostVisitedReposList;
private final Context ctx;
- class MostVisitedViewHolder extends RecyclerView.ViewHolder {
+ public class MostVisitedViewHolder extends RecyclerView.ViewHolder {
private Repository repository;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationAddUserToTeamMemberAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationAddUserToTeamMemberAdapter.java
index d12e56f6..9e3ab0b9 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationAddUserToTeamMemberAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationAddUserToTeamMemberAdapter.java
@@ -63,7 +63,7 @@ public class OrganizationAddUserToTeamMemberAdapter
holder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
- if (!currentItem.getFullName().equals("")) {
+ if (!currentItem.getFullName().isEmpty()) {
holder.userFullName.setText(Html.fromHtml(currentItem.getFullName()));
} else {
@@ -76,7 +76,7 @@ public class OrganizationAddUserToTeamMemberAdapter
holder.userName.setText(
context.getResources().getString(R.string.usernameWithAt, currentItem.getLogin()));
- if (!currentItem.getAvatarUrl().equals("")) {
+ if (!currentItem.getAvatarUrl().isEmpty()) {
PicassoService.getInstance(context)
.get()
.load(currentItem.getAvatarUrl())
@@ -142,7 +142,7 @@ public class OrganizationAddUserToTeamMemberAdapter
return usersSearchList.size();
}
- class UserSearchViewHolder extends RecyclerView.ViewHolder {
+ public class UserSearchViewHolder extends RecyclerView.ViewHolder {
private final ImageView userAvatar;
private final TextView userFullName;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamMembersPreviewAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamMembersPreviewAdapter.java
index dcbeee4a..fab0b979 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamMembersPreviewAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamMembersPreviewAdapter.java
@@ -55,7 +55,7 @@ public class OrganizationTeamMembersPreviewAdapter
return userData.size();
}
- static class ViewHolder extends RecyclerView.ViewHolder {
+ public static class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView avatar;
diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamRepositoriesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamRepositoriesAdapter.java
index 71a8ea74..1c693fa6 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamRepositoriesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamRepositoriesAdapter.java
@@ -50,7 +50,7 @@ public class OrganizationTeamRepositoriesAdapter
reposArr = new ArrayList<>();
}
- class TeamReposViewHolder extends RecyclerView.ViewHolder {
+ public class TeamReposViewHolder extends RecyclerView.ViewHolder {
private Repository repoInfo;
@@ -75,7 +75,7 @@ public class OrganizationTeamRepositoriesAdapter
new Handler(Looper.getMainLooper())
.postDelayed(
() -> {
- if (reposArr.size() > 0) {
+ if (!reposArr.isEmpty()) {
for (int i = 0; i < reposArr.size(); i++) {
if (!reposArr.get(i).getName().equals(repoInfo.getName())) {
addRepoButtonAdd.setVisibility(View.VISIBLE);
@@ -144,7 +144,7 @@ public class OrganizationTeamRepositoriesAdapter
.getColor(currentItem.getName()),
14);
- if (currentItem.getAvatarUrl() != null && !currentItem.getAvatarUrl().equals("")) {
+ if (currentItem.getAvatarUrl() != null && !currentItem.getAvatarUrl().isEmpty()) {
PicassoService.getInstance(context)
.get()
.load(currentItem.getAvatarUrl())
diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamsAdapter.java
index 1e6f143f..7a31b0c2 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationTeamsAdapter.java
@@ -1,5 +1,6 @@
package org.mian.gitnex.adapters;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
@@ -38,7 +39,7 @@ public class OrganizationTeamsAdapter
private final OrganizationPermissions permissions;
private final String orgName;
- static class OrgTeamsViewHolder extends RecyclerView.ViewHolder {
+ public static class OrgTeamsViewHolder extends RecyclerView.ViewHolder {
private Team team;
@@ -101,6 +102,7 @@ public class OrganizationTeamsAdapter
return new OrganizationTeamsAdapter.OrgTeamsViewHolder(v);
}
+ @SuppressLint("NotifyDataSetChanged")
@Override
public void onBindViewHolder(
@NonNull OrganizationTeamsAdapter.OrgTeamsViewHolder holder, int position) {
@@ -126,7 +128,7 @@ public class OrganizationTeamsAdapter
@NonNull Response> response) {
if (response.isSuccessful()
&& response.body() != null
- && response.body().size() > 0) {
+ && !response.body().isEmpty()) {
holder.membersPreviewFrame.setVisibility(View.VISIBLE);
holder.userInfos.addAll(
@@ -189,6 +191,7 @@ public class OrganizationTeamsAdapter
return results;
}
+ @SuppressLint("NotifyDataSetChanged")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
teamList.clear();
diff --git a/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java
index dff86717..128a4308 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/OrganizationsListAdapter.java
@@ -182,7 +182,7 @@ public class OrganizationsListAdapter extends RecyclerView.Adapter
this.userInfo = userInfo;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
- if (!userInfo.getFullName().equals("")) {
+ if (!userInfo.getFullName().isEmpty()) {
userFullName.setText(Html.fromHtml(userInfo.getFullName()));
userName.setText(
context.getResources()
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java
index 245f053c..f2898d56 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java
@@ -35,6 +35,7 @@ import org.mian.gitnex.databinding.CustomEditAvatarDialogBinding;
import org.mian.gitnex.databinding.CustomEditProfileBinding;
import org.mian.gitnex.databinding.FragmentProfileDetailBinding;
import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.AppDatabaseSettings;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.Markdown;
@@ -62,6 +63,7 @@ public class DetailFragment extends Fragment {
private int imgRadius;
private static Uri avatarUri = null;
public static boolean refProfile = false;
+ public boolean itsMe = false;
public DetailFragment() {}
@@ -109,6 +111,7 @@ public class DetailFragment extends Fragment {
if (username.equals(((BaseActivity) context).getAccount().getAccount().getUserName())) {
binding.metaProfile.setVisibility(View.VISIBLE);
+ itsMe = true;
} else {
binding.metaProfile.setVisibility(View.GONE);
}
@@ -366,7 +369,19 @@ public class DetailFragment extends Fragment {
getString(
R.string.usernameWithAt,
response.body().getLogin()));
- binding.userEmail.setText(email);
+
+ if (Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ context,
+ AppDatabaseSettings
+ .APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY))
+ && itsMe) {
+ binding.userEmail.setText(
+ getString(R.string.strPrivate).toUpperCase());
+ binding.userEmail.setAlpha(.4F);
+ } else {
+ binding.userEmail.setText(email);
+ }
binding.userFollowersCount.setText(
String.format(
@@ -389,13 +404,25 @@ public class DetailFragment extends Fragment {
String[] userLanguageCodes =
response.body().getLanguage().split("-");
- if (userLanguageCodes.length >= 2) {
- Locale locale =
- new Locale(
- userLanguageCodes[0], userLanguageCodes[1]);
- binding.userLang.setText(locale.getDisplayLanguage());
+ if (Boolean.parseBoolean(
+ AppDatabaseSettings.getSettingsValue(
+ context,
+ AppDatabaseSettings
+ .APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY))
+ && itsMe) {
+ binding.userLang.setText(
+ getString(R.string.strPrivate).toUpperCase());
+ binding.userLang.setAlpha(.4F);
} else {
- binding.userLang.setText(locale.getDisplayLanguage());
+ if (userLanguageCodes.length >= 2) {
+ Locale locale =
+ new Locale(
+ userLanguageCodes[0],
+ userLanguageCodes[1]);
+ binding.userLang.setText(locale.getDisplayLanguage());
+ } else {
+ binding.userLang.setText(locale.getDisplayLanguage());
+ }
}
PicassoService.getInstance(context)
@@ -415,6 +442,30 @@ public class DetailFragment extends Fragment {
TimeHelper.customDateFormatForToastDateFormat(
response.body().getCreated()),
context));
+ if (!response.body().getWebsite().isEmpty()) {
+ binding.website.setText(response.body().getWebsite());
+ } else {
+ binding.website.setText(R.string.noDataWebsite);
+ binding.website.setAlpha(.4F);
+ }
+
+ if (!response.body().getLocation().isEmpty()) {
+ binding.location.setText(response.body().getLocation());
+ } else {
+ binding.location.setText(R.string.noDataLocation);
+ binding.location.setAlpha(.4F);
+ }
+
+ if (!response.body().getDescription().isEmpty()) {
+ Markdown.render(
+ context,
+ response.body().getDescription(),
+ binding.bio);
+ } else {
+ binding.bio.setText(R.string.noDataBio);
+ binding.bio.setAlpha(.4F);
+ }
+
break;
case 401:
diff --git a/app/src/main/java/org/mian/gitnex/helpers/AppDatabaseSettings.java b/app/src/main/java/org/mian/gitnex/helpers/AppDatabaseSettings.java
index 43c4a0f8..6503aac7 100644
--- a/app/src/main/java/org/mian/gitnex/helpers/AppDatabaseSettings.java
+++ b/app/src/main/java/org/mian/gitnex/helpers/AppDatabaseSettings.java
@@ -62,6 +62,11 @@ public class AppDatabaseSettings {
public static String APP_IMAGES_CACHE_DEFAULT = "1";
public static String APP_IMAGES_CACHE_SIZE_KEY = "app_images_cache_size";
public static String APP_IMAGES_CACHE_SIZE_DEFAULT = "100 MB";
+ public static String APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY =
+ "app_user_profile_hide_email_lang";
+ public static String APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_DEFAULT = "false";
+ public static String APP_USER_HIDE_EMAIL_IN_NAV_KEY = "app_user_hide_email_nav";
+ public static String APP_USER_HIDE_EMAIL_IN_NAV_DEFAULT = "false";
public static void initDefaultSettings(Context ctx) {
@@ -190,6 +195,18 @@ public class AppDatabaseSettings {
APP_IMAGES_CACHE_SIZE_DEFAULT,
APP_IMAGES_CACHE_SIZE_DEFAULT);
}
+ if (appSettingsApi.fetchSettingCountByKey(APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY) == 0) {
+ appSettingsApi.insertNewSetting(
+ APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_KEY,
+ APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_DEFAULT,
+ APP_USER_PROFILE_HIDE_EMAIL_LANGUAGE_DEFAULT);
+ }
+ if (appSettingsApi.fetchSettingCountByKey(APP_USER_HIDE_EMAIL_IN_NAV_KEY) == 0) {
+ appSettingsApi.insertNewSetting(
+ APP_USER_HIDE_EMAIL_IN_NAV_KEY,
+ APP_USER_HIDE_EMAIL_IN_NAV_DEFAULT,
+ APP_USER_HIDE_EMAIL_IN_NAV_DEFAULT);
+ }
if (appSettingsApi.fetchSettingCountByKey("prefsMigration") == 0) {
appSettingsApi.insertNewSetting("prefsMigration", "true", "true");
diff --git a/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java b/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java
index 162a813a..bf36330e 100644
--- a/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java
+++ b/app/src/main/java/org/mian/gitnex/helpers/SnackBar.java
@@ -34,7 +34,7 @@ public class SnackBar {
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
snackBar.setBackgroundTint(context.getColor(R.color.cardBackground));
- textView.setTextColor(context.getColor(R.color.warningColor));
+ textView.setTextColor(context.getColor(R.color.colorWhite));
snackBar.show();
}
@@ -43,7 +43,7 @@ public class SnackBar {
View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text);
snackBar.setBackgroundTint(context.getColor(R.color.cardBackground));
- textView.setTextColor(context.getColor(R.color.darkRed));
+ textView.setTextColor(context.getColor(R.color.colorWhite));
snackBar.show();
}
}
diff --git a/app/src/main/java/org/mian/gitnex/notifications/Notifications.java b/app/src/main/java/org/mian/gitnex/notifications/Notifications.java
index 2a7169e0..29a6dc40 100644
--- a/app/src/main/java/org/mian/gitnex/notifications/Notifications.java
+++ b/app/src/main/java/org/mian/gitnex/notifications/Notifications.java
@@ -106,9 +106,17 @@ public class Notifications {
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.pageTitleNotifications)
+ .setCancelable(false)
.setMessage(context.getString(R.string.openAppSettings))
.setNeutralButton(
- R.string.cancelButton, (dialog, which) -> dialog.dismiss())
+ R.string.cancelButton,
+ (dialog, which) -> {
+ dialog.dismiss();
+ AppDatabaseSettings.updateSettingsValue(
+ context,
+ "false",
+ AppDatabaseSettings.APP_NOTIFICATIONS_KEY);
+ })
.setPositiveButton(
R.string.isOpen,
(dialog, which) -> {
diff --git a/app/src/main/res/drawable/ic_file_description.xml b/app/src/main/res/drawable/ic_file_description.xml
new file mode 100644
index 00000000..83140da4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_file_description.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_issue_detail.xml b/app/src/main/res/layout/activity_issue_detail.xml
index a758fa50..cc7eda83 100644
--- a/app/src/main/res/layout/activity_issue_detail.xml
+++ b/app/src/main/res/layout/activity_issue_detail.xml
@@ -90,7 +90,7 @@
android:paddingStart="@dimen/dimen8dp"
android:paddingTop="@dimen/dimen2dp"
android:paddingEnd="@dimen/dimen8dp"
- android:paddingBottom="@dimen/dimen104dp">
+ android:paddingBottom="@dimen/dimen120dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_profile_detail.xml b/app/src/main/res/layout/fragment_profile_detail.xml
index ad3ed811..2eaea4f4 100644
--- a/app/src/main/res/layout/fragment_profile_detail.xml
+++ b/app/src/main/res/layout/fragment_profile_detail.xml
@@ -51,12 +51,12 @@
tools:ignore="UseCompoundDrawables">
+ app:cardCornerRadius="@dimen/dimen16dp">
@@ -203,6 +203,7 @@
android:layout_height="wrap_content"
android:alpha="0.9"
android:textColor="?attr/primaryTextColor"
+ android:autoLink="email"
android:textSize="@dimen/dimen14sp" />
@@ -214,76 +215,191 @@
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="horizontal">
-
-
-
-
-
-
-
-
-
-
+
+ android:layout_marginStart="@dimen/dimen16dp"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
-
+ android:text="@string/websiteText"
+ android:textColor="?attr/primaryTextColor"
+ android:textSize="@dimen/dimen16sp" />
-
-
-
-
-
-
-
+ android:alpha="0.9"
+ android:textColor="?attr/primaryTextColor"
+ android:autoLink="web"
+ android:textSize="@dimen/dimen14sp" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/nav_header.xml b/app/src/main/res/layout/nav_header.xml
index 5ed9d1ec..ffce9148 100644
--- a/app/src/main/res/layout/nav_header.xml
+++ b/app/src/main/res/layout/nav_header.xml
@@ -30,7 +30,7 @@
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen60dp"
android:layout_height="@dimen/dimen60dp"
- app:cardCornerRadius="@dimen/dimen32dp"
+ app:cardCornerRadius="@dimen/dimen16dp"
app:cardElevation="@dimen/dimen0dp">
+ android:title="@string/navMyIssues"/>
- An error occurred while restoring from the backup file.
Restore from Backup
You are about to restore from a GitNex-generated backup file. This will restore user accounts, settings, notes, and data related to repositories.\n\nClick Restore to start the process.
+ Set Email and Language as Private
+ You can set your email and language to private to hide them on your profile screen
+ Hide Email in Drawer
+ You can enable this option to hide your email in the app navigation drawer
No more data available
@@ -452,6 +456,7 @@
Watchers
No website found
No description found
+ No bio found
No location found
Star
Watcher
@@ -550,6 +555,7 @@
License
Title
Description
+ Bio
Explore users
diff --git a/app/src/main/res/xml/changelog.xml b/app/src/main/res/xml/changelog.xml
index 36279af1..48e13ff5 100644
--- a/app/src/main/res/xml/changelog.xml
+++ b/app/src/main/res/xml/changelog.xml
@@ -1,15 +1,8 @@
-
- New: Update user avatar
- New: New popup screen to add email
- New: Insert note to issue/pr/release description
- New: New reply/comment UI
- Improvement: Hide app contents when biometric is enabled
- Bugfix: Fix back button closing the app
- Bugfix: Fix profile fields data
- Bugfix: Fix text color highlighting
+
+ Under development
diff --git a/build.gradle b/build.gradle
index 445001b6..0257fcbd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,5 +20,5 @@ allprojects {
}
tasks.register('clean', Delete) {
- delete rootProject.buildDir
+ delete rootProject.layout.buildDirectory
}