diff --git a/README.md b/README.md
index bc8be288..eeaedf1a 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@ Thanks to all the open source libraries, contributors, and donors.
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
- [ramseth001/TextDrawable](https://github.com/ramseth001/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)
+- [skydoves/ColorPickerView](https://github.com/skydoves/ColorPickerView)
- [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView)
- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView)
- [apache/commons](https://github.com/apache/commons-io)
diff --git a/app/build.gradle b/app/build.gradle
index 1988c22a..3dc10f92 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,7 +4,6 @@ plugins {
apply plugin: 'com.android.application'
android {
- compileSdkVersion 34
defaultConfig {
applicationId "org.mian.gitnex"
minSdkVersion 23
@@ -13,8 +12,9 @@ android {
versionName "5.3.0-dev"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ compileSdk 34
}
- flavorDimensions "default"
+ flavorDimensions = ["default"]
productFlavors {
free {
applicationId "org.mian.gitnex"
@@ -57,13 +57,13 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'com.google.android.material:material:1.11.0-alpha03'
- implementation 'androidx.compose.material3:material3:1.2.0-alpha08'
- implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-alpha08'
+ implementation 'com.google.android.material:material:1.11.0'
+ implementation 'androidx.compose.material3:material3:1.2.0-beta02'
+ implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-beta02'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
- implementation "androidx.lifecycle:lifecycle-viewmodel:2.6.2"
+ 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'
@@ -76,7 +76,7 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
implementation 'org.ocpsoft.prettytime:prettytime:5.0.7.Final'
- implementation 'com.github.Pes8:android-material-color-picker-dialog:master'
+ implementation "com.github.skydoves:colorpickerview:2.3.0"
implementation "io.noties.markwon:core:4.6.2"
implementation "io.noties.markwon:ext-latex:4.6.2"
implementation "io.noties.markwon:ext-strikethrough:4.6.2"
@@ -99,18 +99,18 @@ dependencies {
implementation 'ch.acra:acra-mail:5.11.2'
implementation 'ch.acra:acra-limiter:5.11.2'
implementation 'ch.acra:acra-notification:5.11.2'
- implementation 'androidx.room:room-runtime:2.5.2'
- annotationProcessor 'androidx.room:room-compiler:2.5.2'
- implementation "androidx.work:work-runtime:2.8.1"
+ 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 "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
//noinspection GradleDependency
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.github.chrisvest:stormpot:2.4.2'
- implementation 'androidx.browser:browser:1.6.0'
+ implementation 'androidx.browser:browser:1.7.0'
implementation 'com.google.android.flexbox:flexbox:3.0.0'
- implementation('org.codeberg.gitnex:tea4j-autodeploy:65f700d036') {
+ implementation('org.codeberg.gitnex:tea4j-autodeploy:4646f53557') {
exclude module: 'org.apache.oltu.oauth2.common'
}
implementation 'io.github.amrdeveloper:codeview:1.3.8'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 27eafece..9d0af8f6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
+
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
@@ -69,13 +73,16 @@
android:theme="@style/AppTheme.NoActionBar"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
+ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
+ android:windowSoftInputMode="adjustResize"/>
@@ -165,7 +176,7 @@
+ android:windowSoftInputMode="adjustResize"/>
processAddNewEmail();
private ActivityAccountSettingsEmailBinding activityAccountSettingsEmailBinding;
@Override
@@ -41,56 +35,42 @@ public class AccountSettingsEmailActivity extends BaseActivity {
ActivityAccountSettingsEmailBinding.inflate(getLayoutInflater());
setContentView(activityAccountSettingsEmailBinding.getRoot());
- boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
+ activityAccountSettingsEmailBinding.topAppBar.setNavigationOnClickListener(v -> finish());
- InputMethodManager imm =
- (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ activityAccountSettingsEmailBinding.topAppBar.setOnMenuItemClickListener(
+ menuItem -> {
+ int id = menuItem.getItemId();
- activityAccountSettingsEmailBinding.userEmail.requestFocus();
- assert imm != null;
- imm.showSoftInput(
- activityAccountSettingsEmailBinding.userEmail, InputMethodManager.SHOW_IMPLICIT);
-
- initCloseListener();
- activityAccountSettingsEmailBinding.close.setOnClickListener(onClickListener);
-
- if (!connToInternet) {
-
- disableProcessButton();
- } else {
-
- activityAccountSettingsEmailBinding.addEmailButton.setOnClickListener(addEmailListener);
- }
+ if (id == R.id.save) {
+ processAddNewEmail();
+ return true;
+ } else {
+ return super.onOptionsItemSelected(menuItem);
+ }
+ });
}
private void processAddNewEmail() {
- boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
-
String newUserEmail =
Objects.requireNonNull(activityAccountSettingsEmailBinding.userEmail.getText())
.toString()
.trim();
- if (!connToInternet) {
-
- Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
- return;
- }
-
if (newUserEmail.equals("")) {
- Toasty.error(ctx, getString(R.string.emailErrorEmpty));
+ SnackBar.error(
+ ctx, findViewById(android.R.id.content), getString(R.string.emailErrorEmpty));
return;
} else if (!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
- Toasty.warning(ctx, getString(R.string.emailErrorInvalid));
+ SnackBar.error(
+ ctx, findViewById(android.R.id.content), getString(R.string.emailErrorInvalid));
return;
}
List newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
- disableProcessButton();
addNewEmail(newEmailList);
}
@@ -111,54 +91,44 @@ public class AccountSettingsEmailActivity extends BaseActivity {
if (response.code() == 201) {
- Toasty.success(ctx, getString(R.string.emailAddedText));
+ SnackBar.info(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.emailAddedText));
AccountSettingsEmailsFragment.refreshEmails = true;
- enableProcessButton();
- finish();
+ new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) {
- enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 403) {
- enableProcessButton();
- Toasty.error(ctx, ctx.getString(R.string.authorizeError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.authorizeError));
} else if (response.code() == 404) {
- enableProcessButton();
- Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.apiNotFound));
} else if (response.code() == 422) {
- enableProcessButton();
- Toasty.warning(ctx, ctx.getString(R.string.emailErrorInUse));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.emailErrorInUse));
} else {
- enableProcessButton();
- Toasty.error(ctx, getString(R.string.genericError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericError));
}
}
@Override
- public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
-
- Log.e("onFailure", t.toString());
- enableProcessButton();
- }
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {}
});
}
-
- private void initCloseListener() {
-
- onClickListener = view -> finish();
- }
-
- private void disableProcessButton() {
-
- activityAccountSettingsEmailBinding.addEmailButton.setEnabled(false);
- }
-
- private void enableProcessButton() {
-
- activityAccountSettingsEmailBinding.addEmailButton.setEnabled(true);
- }
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java b/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java
index 822d7453..66fc19b5 100644
--- a/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/AddNewAccountActivity.java
@@ -3,8 +3,7 @@ package org.mian.gitnex.activities;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
+import android.os.Handler;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -22,7 +21,7 @@ import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.ActivityAddNewAccountBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.PathsHelper;
-import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.UrlHelper;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.structs.Protocol;
@@ -34,7 +33,6 @@ import retrofit2.Callback;
*/
public class AddNewAccountActivity extends BaseActivity {
- private View.OnClickListener onClickListener;
private ActivityAddNewAccountBinding viewBinding;
private String spinnerSelectedValue;
@@ -52,8 +50,6 @@ public class AddNewAccountActivity extends BaseActivity {
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
- initCloseListener();
- viewBinding.close.setOnClickListener(onClickListener);
viewBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl"));
viewBinding.loginToken.setText(getIntent().getStringExtra("token"));
String scheme = getIntent().getStringExtra("scheme");
@@ -68,20 +64,22 @@ public class AddNewAccountActivity extends BaseActivity {
ArrayAdapter adapterProtocols =
new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
+ viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
+
viewBinding.protocolSpinner.setAdapter(adapterProtocols);
viewBinding.protocolSpinner.setOnItemClickListener(
(parent, view1, position, id) ->
spinnerSelectedValue = String.valueOf(parent.getItemAtPosition(position)));
- viewBinding.addNewAccount.setOnClickListener(
- login -> {
- boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
- if (!connToInternet) {
-
- Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
- } else {
+ viewBinding.topAppBar.setOnMenuItemClickListener(
+ menuItem -> {
+ int id = menuItem.getItemId();
+ if (id == R.id.addAccount) {
processLogin();
+ return true;
+ } else {
+ return super.onOptionsItemSelected(menuItem);
}
});
}
@@ -102,19 +100,26 @@ public class AddNewAccountActivity extends BaseActivity {
if (protocol == null) {
- Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.protocolEmptyError));
return;
}
if (instanceUrlET.equals("")) {
- Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL));
+ SnackBar.error(
+ ctx, findViewById(android.R.id.content), getString(R.string.emptyFieldURL));
return;
}
if (loginToken.equals("")) {
- Toasty.error(ctx, getResources().getString(R.string.loginTokenError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.loginTokenError));
return;
}
@@ -132,7 +137,8 @@ public class AddNewAccountActivity extends BaseActivity {
} catch (Exception e) {
- Toasty.error(ctx, getResources().getString(R.string.malformedUrl));
+ SnackBar.error(
+ ctx, findViewById(android.R.id.content), getString(R.string.malformedUrl));
}
}
@@ -157,8 +163,10 @@ public class AddNewAccountActivity extends BaseActivity {
if (!Version.valid(version.getVersion())) {
- Toasty.error(
- ctx, getResources().getString(R.string.versionUnknown));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.versionUnknown));
return;
}
@@ -192,12 +200,18 @@ public class AddNewAccountActivity extends BaseActivity {
login(instanceUrl, loginToken);
} else {
- Toasty.warning(
+ SnackBar.error(
ctx,
- getResources().getString(R.string.versionUnsupportedNew));
+ findViewById(android.R.id.content),
+ getString(R.string.versionUnsupportedNew));
login(instanceUrl, loginToken);
}
+ } else if (responseVersion.code() == 401) {
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.unauthorizedApiError));
} else if (responseVersion.code() == 403) {
login(instanceUrl, loginToken);
@@ -213,9 +227,10 @@ public class AddNewAccountActivity extends BaseActivity {
public void onFailure(
@NonNull Call callVersion, @NonNull Throwable t) {
- Log.e("onFailure-versionCheck", t.toString());
- Toasty.error(
- ctx, getResources().getString(R.string.genericServerResponseError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericServerResponseError));
}
});
}
@@ -291,21 +306,20 @@ public class AddNewAccountActivity extends BaseActivity {
defaultPagingNumber);
UserAccount account = userAccountsApi.getAccountById((int) id);
AppUtil.switchToAccount(AddNewAccountActivity.this, account);
- Toasty.success(
+ SnackBar.success(
ctx,
- getResources().getString(R.string.accountAddedMessage));
+ findViewById(android.R.id.content),
+ getString(R.string.accountAddedMessage));
MainActivity.refActivity = true;
- finish();
+ new Handler().postDelayed(() -> finish(), 3000);
} else {
UserAccount account =
userAccountsApi.getAccountByName(accountName);
if (account.isLoggedIn()) {
- Toasty.warning(
+ SnackBar.error(
ctx,
- getResources()
- .getString(
- R.string
- .accountAlreadyExistsError));
+ findViewById(android.R.id.content),
+ getString(R.string.accountAlreadyExistsError));
AppUtil.switchToAccount(ctx, account);
} else {
userAccountsApi.updateTokenByAccountName(
@@ -315,34 +329,31 @@ public class AddNewAccountActivity extends BaseActivity {
AddNewAccountActivity.this, account);
}
}
- finish();
break;
case 401:
- Toasty.error(
+ SnackBar.error(
ctx,
- getResources().getString(R.string.unauthorizedApiError));
+ findViewById(android.R.id.content),
+ getString(R.string.unauthorizedApiError));
break;
default:
- Toasty.error(
+ SnackBar.error(
ctx,
- getResources()
- .getString(
- R.string.genericApiError, response.code()));
+ findViewById(android.R.id.content),
+ getString(R.string.genericApiError, response.code()));
}
}
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
- Toasty.error(ctx, getResources().getString(R.string.genericError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericError));
}
});
}
-
- private void initCloseListener() {
-
- onClickListener = view -> finish();
- }
}
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 26c2402e..ce8ee3da 100644
--- a/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/BaseActivity.java
@@ -94,7 +94,7 @@ public abstract class BaseActivity extends AppCompatActivity {
AppUtil.setAppLocale(getResources(), locale);
}
- Notifications.startWorker(appCtx);
+ Notifications.startWorker(ctx);
}
public void onResume() {
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 683b716d..1fe379f0 100644
--- a/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/CreateFileActivity.java
@@ -2,15 +2,13 @@ package org.mian.gitnex.activities;
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.util.Log;
+import android.os.Handler;
+import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
-import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
@@ -29,8 +27,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateFileBinding;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
-import org.mian.gitnex.helpers.NetworkStatusObserver;
-import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call;
import retrofit2.Callback;
@@ -72,16 +69,14 @@ public class CreateFileActivity extends BaseActivity {
repository = RepositoryContext.fromIntent(getIntent());
- TextView toolbarTitle = binding.toolbarTitle;
+ binding.topAppBar.setNavigationOnClickListener(v -> finish());
- binding.newFileName.requestFocus();
+ MenuItem create = binding.topAppBar.getMenu().getItem(0);
+ MenuItem update = binding.topAppBar.getMenu().getItem(1);
+ MenuItem delete = binding.topAppBar.getMenu().getItem(2);
+ update.setVisible(false);
+ delete.setVisible(false);
- InputMethodManager inputMethodManager =
- (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
- assert inputMethodManager != null;
- inputMethodManager.showSoftInput(binding.newFileName, InputMethodManager.SHOW_IMPLICIT);
-
- binding.close.setOnClickListener(view -> finish());
binding.newFileContent.setOnTouchListener(
(touchView, motionEvent) -> {
touchView.getParent().requestDisallowInterceptTouchEvent(true);
@@ -103,12 +98,13 @@ public class CreateFileActivity extends BaseActivity {
filePath = getIntent().getStringExtra("filePath");
fileSha = getIntent().getStringExtra("fileSha");
- toolbarTitle.setText(getString(R.string.deleteGenericTitle, filePath));
-
- binding.newFileCreate.setText(R.string.deleteFile);
+ binding.topAppBar.setTitle(getString(R.string.deleteGenericTitle, filePath));
binding.newFileNameLayout.setVisibility(View.GONE);
binding.newFileContentLayout.setVisibility(View.GONE);
+ delete.setVisible(true);
+ create.setVisible(false);
+ update.setVisible(false);
}
if (getIntent().getStringExtra("filePath") != null
@@ -118,20 +114,20 @@ public class CreateFileActivity extends BaseActivity {
filePath = getIntent().getStringExtra("filePath");
fileSha = getIntent().getStringExtra("fileSha");
- toolbarTitle.setText(getString(R.string.editFileText, filePath));
+ binding.topAppBar.setTitle(getString(R.string.editFileText, filePath));
- binding.newFileCreate.setText(R.string.editFile);
binding.newFileName.setText(filePath);
binding.newFileName.setEnabled(false);
binding.newFileName.setFocusable(false);
binding.newFileContent.setText(getIntent().getStringExtra("fileContents"));
+ update.setVisible(true);
+ create.setVisible(false);
+ delete.setVisible(false);
}
getBranches(repository.getOwner(), repository.getName());
- disableProcessButton();
-
binding.openCodeEditor.setOnClickListener(
v ->
launchCodeEditorActivityForResult(
@@ -139,13 +135,23 @@ public class CreateFileActivity extends BaseActivity {
FilenameUtils.getExtension(
String.valueOf(binding.newFileName.getText()))));
- NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx);
- networkStatusObserver.registerNetworkStatusListener(
- hasNetworkConnection ->
- runOnUiThread(
- () -> binding.newFileCreate.setEnabled(hasNetworkConnection)));
+ binding.topAppBar.setOnMenuItemClickListener(
+ menuItem -> {
+ int id = menuItem.getItemId();
- binding.newFileCreate.setOnClickListener(v -> processNewFile());
+ if (id == R.id.create) {
+ processNewFile();
+ return true;
+ } else if (id == R.id.update) {
+ processNewFile();
+ return true;
+ } else if (id == R.id.delete) {
+ processNewFile();
+ return true;
+ } else {
+ return super.onOptionsItemSelected(menuItem);
+ }
+ });
}
public void launchCodeEditorActivityForResult(String fileContent, String fileExtension) {
@@ -175,29 +181,39 @@ public class CreateFileActivity extends BaseActivity {
: "";
if (!AppUtil.hasNetworkConnection(appCtx)) {
- Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.checkNetConnection));
return;
}
if (((newFileName.isEmpty() || newFileContent.isEmpty())
&& fileAction != FILE_ACTION_DELETE)
|| newFileCommitMessage.isEmpty()) {
- Toasty.error(ctx, getString(R.string.newFileRequiredFields));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.newFileRequiredFields));
return;
}
if (!AppUtil.checkStringsWithDash(newFileBranchName)) {
- Toasty.error(ctx, getString(R.string.newFileInvalidBranchName));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.newFileInvalidBranchName));
return;
}
if (newFileCommitMessage.length() > 255) {
- Toasty.warning(ctx, getString(R.string.newFileCommitMessageError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.newFileCommitMessageError));
return;
}
- disableProcessButton();
-
switch (fileAction) {
case FILE_ACTION_CREATE:
createNewFile(
@@ -264,39 +280,40 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) {
case 201:
- enableProcessButton();
- Toasty.success(ctx, getString(R.string.newFileSuccessMessage));
+ SnackBar.success(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.newFileSuccessMessage));
Intent result = new Intent();
result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction);
setResult(200, result);
RepoDetailActivity.updateFABActions = true;
- finish();
+ new Handler().postDelayed(() -> finish(), 3000);
break;
case 401:
- enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx);
break;
case 404:
- enableProcessButton();
- Toasty.warning(ctx, getString(R.string.apiNotFound));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.apiNotFound));
break;
default:
- enableProcessButton();
- Toasty.error(ctx, getString(R.string.genericError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericError));
break;
}
}
@Override
- public void onFailure(@NonNull Call call, @NonNull Throwable t) {
-
- Log.e("onFailure", t.toString());
- enableProcessButton();
- }
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {}
});
}
@@ -332,9 +349,9 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) {
case 200:
- enableProcessButton();
- Toasty.info(
+ SnackBar.success(
ctx,
+ findViewById(android.R.id.content),
getString(
R.string.deleteFileMessage,
repository.getBranchRef()));
@@ -342,33 +359,32 @@ public class CreateFileActivity extends BaseActivity {
result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction);
setResult(200, result);
- finish();
+ new Handler().postDelayed(() -> finish(), 3000);
break;
case 401:
- enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx);
break;
case 404:
- enableProcessButton();
- Toasty.info(ctx, getString(R.string.apiNotFound));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.apiNotFound));
break;
default:
- enableProcessButton();
- Toasty.info(ctx, getString(R.string.genericError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericError));
break;
}
}
@Override
public void onFailure(
- @NonNull Call call, @NonNull Throwable t) {
-
- Log.e("onFailure", t.toString());
- enableProcessButton();
- }
+ @NonNull Call call, @NonNull Throwable t) {}
});
}
@@ -406,38 +422,39 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) {
case 200:
- enableProcessButton();
- Toasty.info(ctx, getString(R.string.editFileMessage, branchName));
+ SnackBar.success(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.editFileMessage, branchName));
Intent result = new Intent();
result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction);
setResult(200, result);
- finish();
+ new Handler().postDelayed(() -> finish(), 3000);
break;
case 401:
- enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx);
break;
case 404:
- enableProcessButton();
- Toasty.info(ctx, getString(R.string.apiNotFound));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.apiNotFound));
break;
default:
- enableProcessButton();
- Toasty.info(ctx, getString(R.string.genericError));
+ SnackBar.error(
+ ctx,
+ findViewById(android.R.id.content),
+ getString(R.string.genericError));
break;
}
}
@Override
- public void onFailure(@NonNull Call call, @NonNull Throwable t) {
-
- Log.e("onFailure", t.toString());
- enableProcessButton();
- }
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {}
});
}
@@ -468,27 +485,14 @@ public class CreateFileActivity extends BaseActivity {
binding.newFileBranches.setAdapter(adapter);
binding.newFileBranches.setText(repository.getBranchRef(), false);
-
- enableProcessButton();
}
}
@Override
- public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
-
- Log.e("onFailure", t.toString());
- }
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {}
});
}
- private void disableProcessButton() {
- binding.newFileCreate.setEnabled(false);
- }
-
- private void enableProcessButton() {
- binding.newFileCreate.setEnabled(true);
- }
-
@Override
public void onResume() {
super.onResume();
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 95171c6b..5fa8727f 100644
--- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java
@@ -1,27 +1,37 @@
package org.mian.gitnex.activities;
import android.annotation.SuppressLint;
-import android.app.DatePickerDialog;
-import android.content.Context;
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.TextView;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import com.google.android.material.bottomsheet.BottomSheetDialog;
+import com.google.android.material.datepicker.MaterialDatePicker;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser;
+import java.io.File;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
+import java.util.TimeZone;
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import org.gitnex.tea4j.v2.models.Attachment;
import org.gitnex.tea4j.v2.models.CreateIssueOption;
import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.Label;
@@ -31,17 +41,20 @@ import org.mian.gitnex.R;
import org.mian.gitnex.actions.AssigneesActions;
import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AssigneesListAdapter;
+import org.mian.gitnex.adapters.AttachmentsAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateIssueBinding;
+import org.mian.gitnex.databinding.BottomSheetAttachmentsBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs;
-import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown;
-import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.attachments.AttachmentUtils;
+import org.mian.gitnex.helpers.attachments.AttachmentsModel;
import org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call;
import retrofit2.Callback;
@@ -50,17 +63,15 @@ import retrofit2.Callback;
* @author M M Arif
*/
public class CreateIssueActivity extends BaseActivity
- implements View.OnClickListener,
- LabelsListAdapter.LabelsListAdapterListener,
- AssigneesListAdapter.AssigneesListAdapterListener {
+ implements LabelsListAdapter.LabelsListAdapterListener,
+ AssigneesListAdapter.AssigneesListAdapterListener,
+ AttachmentsAdapter.AttachmentsReceiverListener {
private final List