Handle attachments in issue, pr and comments (#1304)

Closes #56

Closes #1313

Closes #1215

Closes #926

Closes #1315

Closes #1321

Closes #1322

Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1304
Co-authored-by: M M Arif <mmarif@swatian.com>
Co-committed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
M M Arif 2024-02-11 13:20:23 +00:00 committed by M M Arif
parent a3fa2344a4
commit 72a2b82558
94 changed files with 5422 additions and 4575 deletions

View File

@ -84,7 +84,7 @@ Thanks to all the open source libraries, contributors, and donors.
- [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime) - [ocpsoft/prettytime](https://github.com/ocpsoft/prettytime)
- [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable) - [ramseth001/TextDrawable](https://github.com/ramseth001/TextDrawable)
- [vdurmont/emoji-java](https://github.com/vdurmont/emoji-java) - [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) - [HamidrezaAmz/BreadcrumbsView](https://github.com/HamidrezaAmz/BreadcrumbsView)
- [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView) - [Baseflow/PhotoView](https://github.com/Baseflow/PhotoView)
- [apache/commons](https://github.com/apache/commons-io) - [apache/commons](https://github.com/apache/commons-io)

View File

@ -4,7 +4,6 @@ plugins {
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 34
defaultConfig { defaultConfig {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
minSdkVersion 23 minSdkVersion 23
@ -13,8 +12,9 @@ android {
versionName "5.3.0-dev" versionName "5.3.0-dev"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileSdk 34
} }
flavorDimensions "default" flavorDimensions = ["default"]
productFlavors { productFlavors {
free { free {
applicationId "org.mian.gitnex" applicationId "org.mian.gitnex"
@ -57,13 +57,13 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0-alpha03' implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.compose.material3:material3:1.2.0-alpha08' implementation 'androidx.compose.material3:material3:1.2.0-beta02'
implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-alpha08' implementation 'androidx.compose.material3:material3-window-size-class:1.2.0-beta02'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02' implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.legacy:legacy-support-v4:1.0.0" 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' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 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.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2' implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
implementation 'org.ocpsoft.prettytime:prettytime:5.0.7.Final' 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:core:4.6.2"
implementation "io.noties.markwon:ext-latex:4.6.2" implementation "io.noties.markwon:ext-latex:4.6.2"
implementation "io.noties.markwon:ext-strikethrough: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-mail:5.11.2'
implementation 'ch.acra:acra-limiter:5.11.2' implementation 'ch.acra:acra-limiter:5.11.2'
implementation 'ch.acra:acra-notification:5.11.2' implementation 'ch.acra:acra-notification:5.11.2'
implementation 'androidx.room:room-runtime:2.5.2' implementation 'androidx.room:room-runtime:2.6.1'
annotationProcessor 'androidx.room:room-compiler:2.5.2' annotationProcessor 'androidx.room:room-compiler:2.6.1'
implementation "androidx.work:work-runtime:2.8.1" implementation "androidx.work:work-runtime:2.9.0"
implementation "io.mikael:urlbuilder:2.0.9" implementation "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2" implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
//noinspection GradleDependency //noinspection GradleDependency
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
implementation 'androidx.biometric:biometric:1.1.0' implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.github.chrisvest:stormpot:2.4.2' 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 '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' exclude module: 'org.apache.oltu.oauth2.common'
} }
implementation 'io.github.amrdeveloper:codeview:1.3.8' implementation 'io.github.amrdeveloper:codeview:1.3.8'

View File

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<application <application
android:name=".core.MainApplication" android:name=".core.MainApplication"
@ -47,13 +48,16 @@
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/>
<activity <activity
android:name=".activities.EditIssueActivity" android:name=".activities.EditIssueActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.CreateNewUserActivity" android:name=".activities.CreateNewUserActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.AccountSettingsEmailActivity" android:name=".activities.AccountSettingsEmailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.AddCollaboratorToRepositoryActivity" android:name=".activities.AddCollaboratorToRepositoryActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/>
@ -69,13 +73,16 @@
android:theme="@style/AppTheme.NoActionBar"/> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".activities.CreateLabelActivity" android:name=".activities.CreateLabelActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.CreateIssueActivity" android:name=".activities.CreateIssueActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.CreateMilestoneActivity" android:name=".activities.CreateMilestoneActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.IssueDetailActivity" android:name=".activities.IssueDetailActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
@ -101,10 +108,12 @@
android:theme="@android:style/Theme.NoTitleBar"/> android:theme="@android:style/Theme.NoTitleBar"/>
<activity <activity
android:name=".activities.CreateRepoActivity" android:name=".activities.CreateRepoActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.CreateOrganizationActivity" android:name=".activities.CreateOrganizationActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.DiffActivity" android:name=".activities.DiffActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
@ -139,13 +148,15 @@
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/>
<activity <activity
android:name=".activities.AddNewAccountActivity" android:name=".activities.AddNewAccountActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.RepositorySettingsActivity" android:name=".activities.RepositorySettingsActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/>
<activity <activity
android:name=".activities.CreatePullRequestActivity" android:name=".activities.CreatePullRequestActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
<activity <activity
android:name=".activities.SettingsGeneralActivity" android:name=".activities.SettingsGeneralActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/> android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"/>
@ -165,7 +176,7 @@
<activity <activity
android:name=".activities.CreateNoteActivity" android:name=".activities.CreateNoteActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation" android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize"/>
<meta-data <meta-data
android:name="com.samsung.android.keepalive.density" android:name="com.samsung.android.keepalive.density"

View File

@ -1,11 +1,8 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.util.Patterns; import android.util.Patterns;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -18,8 +15,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityAccountSettingsEmailBinding; import org.mian.gitnex.databinding.ActivityAccountSettingsEmailBinding;
import org.mian.gitnex.fragments.AccountSettingsEmailsFragment; import org.mian.gitnex.fragments.AccountSettingsEmailsFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.Toasty;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -28,8 +24,6 @@ import retrofit2.Callback;
*/ */
public class AccountSettingsEmailActivity extends BaseActivity { public class AccountSettingsEmailActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private final View.OnClickListener addEmailListener = v -> processAddNewEmail();
private ActivityAccountSettingsEmailBinding activityAccountSettingsEmailBinding; private ActivityAccountSettingsEmailBinding activityAccountSettingsEmailBinding;
@Override @Override
@ -41,56 +35,42 @@ public class AccountSettingsEmailActivity extends BaseActivity {
ActivityAccountSettingsEmailBinding.inflate(getLayoutInflater()); ActivityAccountSettingsEmailBinding.inflate(getLayoutInflater());
setContentView(activityAccountSettingsEmailBinding.getRoot()); setContentView(activityAccountSettingsEmailBinding.getRoot());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); activityAccountSettingsEmailBinding.topAppBar.setNavigationOnClickListener(v -> finish());
InputMethodManager imm = activityAccountSettingsEmailBinding.topAppBar.setOnMenuItemClickListener(
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); menuItem -> {
int id = menuItem.getItemId();
activityAccountSettingsEmailBinding.userEmail.requestFocus(); if (id == R.id.save) {
assert imm != null; processAddNewEmail();
imm.showSoftInput( return true;
activityAccountSettingsEmailBinding.userEmail, InputMethodManager.SHOW_IMPLICIT); } else {
return super.onOptionsItemSelected(menuItem);
initCloseListener(); }
activityAccountSettingsEmailBinding.close.setOnClickListener(onClickListener); });
if (!connToInternet) {
disableProcessButton();
} else {
activityAccountSettingsEmailBinding.addEmailButton.setOnClickListener(addEmailListener);
}
} }
private void processAddNewEmail() { private void processAddNewEmail() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newUserEmail = String newUserEmail =
Objects.requireNonNull(activityAccountSettingsEmailBinding.userEmail.getText()) Objects.requireNonNull(activityAccountSettingsEmailBinding.userEmail.getText())
.toString() .toString()
.trim(); .trim();
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newUserEmail.equals("")) { if (newUserEmail.equals("")) {
Toasty.error(ctx, getString(R.string.emailErrorEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.emailErrorEmpty));
return; return;
} else if (!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { } 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; return;
} }
List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(","))); List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
disableProcessButton();
addNewEmail(newEmailList); addNewEmail(newEmailList);
} }
@ -111,54 +91,44 @@ public class AccountSettingsEmailActivity extends BaseActivity {
if (response.code() == 201) { 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; AccountSettingsEmailsFragment.refreshEmails = true;
enableProcessButton(); new Handler().postDelayed(() -> finish(), 3000);
finish();
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 403) { } else if (response.code() == 403) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); ctx,
findViewById(android.R.id.content),
getString(R.string.authorizeError));
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else if (response.code() == 422) { } else if (response.code() == 422) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, ctx.getString(R.string.emailErrorInUse)); ctx,
findViewById(android.R.id.content),
getString(R.string.emailErrorInUse));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<List<Email>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Email>> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
activityAccountSettingsEmailBinding.addEmailButton.setEnabled(false);
}
private void enableProcessButton() {
activityAccountSettingsEmailBinding.addEmailButton.setEnabled(true);
}
} }

View File

@ -3,8 +3,7 @@ package org.mian.gitnex.activities;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; 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.databinding.ActivityAddNewAccountBinding;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.PathsHelper; 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.UrlHelper;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.structs.Protocol; import org.mian.gitnex.structs.Protocol;
@ -34,7 +33,6 @@ import retrofit2.Callback;
*/ */
public class AddNewAccountActivity extends BaseActivity { public class AddNewAccountActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private ActivityAddNewAccountBinding viewBinding; private ActivityAddNewAccountBinding viewBinding;
private String spinnerSelectedValue; private String spinnerSelectedValue;
@ -52,8 +50,6 @@ public class AddNewAccountActivity extends BaseActivity {
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT)); getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
initCloseListener();
viewBinding.close.setOnClickListener(onClickListener);
viewBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl")); viewBinding.instanceUrl.setText(getIntent().getStringExtra("instanceUrl"));
viewBinding.loginToken.setText(getIntent().getStringExtra("token")); viewBinding.loginToken.setText(getIntent().getStringExtra("token"));
String scheme = getIntent().getStringExtra("scheme"); String scheme = getIntent().getStringExtra("scheme");
@ -68,20 +64,22 @@ public class AddNewAccountActivity extends BaseActivity {
ArrayAdapter<Protocol> adapterProtocols = ArrayAdapter<Protocol> adapterProtocols =
new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values()); new ArrayAdapter<>(ctx, R.layout.list_spinner_items, Protocol.values());
viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
viewBinding.protocolSpinner.setAdapter(adapterProtocols); viewBinding.protocolSpinner.setAdapter(adapterProtocols);
viewBinding.protocolSpinner.setOnItemClickListener( viewBinding.protocolSpinner.setOnItemClickListener(
(parent, view1, position, id) -> (parent, view1, position, id) ->
spinnerSelectedValue = String.valueOf(parent.getItemAtPosition(position))); spinnerSelectedValue = String.valueOf(parent.getItemAtPosition(position)));
viewBinding.addNewAccount.setOnClickListener(
login -> {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if (!connToInternet) { viewBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); int id = menuItem.getItemId();
} else {
if (id == R.id.addAccount) {
processLogin(); processLogin();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
} }
}); });
} }
@ -102,19 +100,26 @@ public class AddNewAccountActivity extends BaseActivity {
if (protocol == null) { if (protocol == null) {
Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.protocolEmptyError));
return; return;
} }
if (instanceUrlET.equals("")) { if (instanceUrlET.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.emptyFieldURL));
return; return;
} }
if (loginToken.equals("")) { if (loginToken.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.loginTokenError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.loginTokenError));
return; return;
} }
@ -132,7 +137,8 @@ public class AddNewAccountActivity extends BaseActivity {
} catch (Exception e) { } 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())) { if (!Version.valid(version.getVersion())) {
Toasty.error( SnackBar.error(
ctx, getResources().getString(R.string.versionUnknown)); ctx,
findViewById(android.R.id.content),
getString(R.string.versionUnknown));
return; return;
} }
@ -192,12 +200,18 @@ public class AddNewAccountActivity extends BaseActivity {
login(instanceUrl, loginToken); login(instanceUrl, loginToken);
} else { } else {
Toasty.warning( SnackBar.error(
ctx, ctx,
getResources().getString(R.string.versionUnsupportedNew)); findViewById(android.R.id.content),
getString(R.string.versionUnsupportedNew));
login(instanceUrl, loginToken); 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) { } else if (responseVersion.code() == 403) {
login(instanceUrl, loginToken); login(instanceUrl, loginToken);
@ -213,9 +227,10 @@ public class AddNewAccountActivity extends BaseActivity {
public void onFailure( public void onFailure(
@NonNull Call<ServerVersion> callVersion, @NonNull Throwable t) { @NonNull Call<ServerVersion> callVersion, @NonNull Throwable t) {
Log.e("onFailure-versionCheck", t.toString()); SnackBar.error(
Toasty.error( ctx,
ctx, getResources().getString(R.string.genericServerResponseError)); findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
@ -291,21 +306,20 @@ public class AddNewAccountActivity extends BaseActivity {
defaultPagingNumber); defaultPagingNumber);
UserAccount account = userAccountsApi.getAccountById((int) id); UserAccount account = userAccountsApi.getAccountById((int) id);
AppUtil.switchToAccount(AddNewAccountActivity.this, account); AppUtil.switchToAccount(AddNewAccountActivity.this, account);
Toasty.success( SnackBar.success(
ctx, ctx,
getResources().getString(R.string.accountAddedMessage)); findViewById(android.R.id.content),
getString(R.string.accountAddedMessage));
MainActivity.refActivity = true; MainActivity.refActivity = true;
finish(); new Handler().postDelayed(() -> finish(), 3000);
} else { } else {
UserAccount account = UserAccount account =
userAccountsApi.getAccountByName(accountName); userAccountsApi.getAccountByName(accountName);
if (account.isLoggedIn()) { if (account.isLoggedIn()) {
Toasty.warning( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(R.string.accountAlreadyExistsError));
R.string
.accountAlreadyExistsError));
AppUtil.switchToAccount(ctx, account); AppUtil.switchToAccount(ctx, account);
} else { } else {
userAccountsApi.updateTokenByAccountName( userAccountsApi.updateTokenByAccountName(
@ -315,34 +329,31 @@ public class AddNewAccountActivity extends BaseActivity {
AddNewAccountActivity.this, account); AddNewAccountActivity.this, account);
} }
} }
finish();
break; break;
case 401: case 401:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources().getString(R.string.unauthorizedApiError)); findViewById(android.R.id.content),
getString(R.string.unauthorizedApiError));
break; break;
default: default:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(R.string.genericApiError, response.code()));
R.string.genericApiError, response.code()));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<User> 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();
}
} }

View File

@ -94,7 +94,7 @@ public abstract class BaseActivity extends AppCompatActivity {
AppUtil.setAppLocale(getResources(), locale); AppUtil.setAppLocale(getResources(), locale);
} }
Notifications.startWorker(appCtx); Notifications.startWorker(ctx);
} }
public void onResume() { public void onResume() {

View File

@ -2,15 +2,13 @@ package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -29,8 +27,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateFileBinding; import org.mian.gitnex.databinding.ActivityCreateFileBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.NetworkStatusObserver; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.contexts.RepositoryContext; import org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -72,16 +69,14 @@ public class CreateFileActivity extends BaseActivity {
repository = RepositoryContext.fromIntent(getIntent()); 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( binding.newFileContent.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
touchView.getParent().requestDisallowInterceptTouchEvent(true); touchView.getParent().requestDisallowInterceptTouchEvent(true);
@ -103,12 +98,13 @@ public class CreateFileActivity extends BaseActivity {
filePath = getIntent().getStringExtra("filePath"); filePath = getIntent().getStringExtra("filePath");
fileSha = getIntent().getStringExtra("fileSha"); fileSha = getIntent().getStringExtra("fileSha");
toolbarTitle.setText(getString(R.string.deleteGenericTitle, filePath)); binding.topAppBar.setTitle(getString(R.string.deleteGenericTitle, filePath));
binding.newFileCreate.setText(R.string.deleteFile);
binding.newFileNameLayout.setVisibility(View.GONE); binding.newFileNameLayout.setVisibility(View.GONE);
binding.newFileContentLayout.setVisibility(View.GONE); binding.newFileContentLayout.setVisibility(View.GONE);
delete.setVisible(true);
create.setVisible(false);
update.setVisible(false);
} }
if (getIntent().getStringExtra("filePath") != null if (getIntent().getStringExtra("filePath") != null
@ -118,20 +114,20 @@ public class CreateFileActivity extends BaseActivity {
filePath = getIntent().getStringExtra("filePath"); filePath = getIntent().getStringExtra("filePath");
fileSha = getIntent().getStringExtra("fileSha"); 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.setText(filePath);
binding.newFileName.setEnabled(false); binding.newFileName.setEnabled(false);
binding.newFileName.setFocusable(false); binding.newFileName.setFocusable(false);
binding.newFileContent.setText(getIntent().getStringExtra("fileContents")); binding.newFileContent.setText(getIntent().getStringExtra("fileContents"));
update.setVisible(true);
create.setVisible(false);
delete.setVisible(false);
} }
getBranches(repository.getOwner(), repository.getName()); getBranches(repository.getOwner(), repository.getName());
disableProcessButton();
binding.openCodeEditor.setOnClickListener( binding.openCodeEditor.setOnClickListener(
v -> v ->
launchCodeEditorActivityForResult( launchCodeEditorActivityForResult(
@ -139,13 +135,23 @@ public class CreateFileActivity extends BaseActivity {
FilenameUtils.getExtension( FilenameUtils.getExtension(
String.valueOf(binding.newFileName.getText())))); String.valueOf(binding.newFileName.getText()))));
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx); binding.topAppBar.setOnMenuItemClickListener(
networkStatusObserver.registerNetworkStatusListener( menuItem -> {
hasNetworkConnection -> int id = menuItem.getItemId();
runOnUiThread(
() -> binding.newFileCreate.setEnabled(hasNetworkConnection)));
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) { public void launchCodeEditorActivityForResult(String fileContent, String fileExtension) {
@ -175,29 +181,39 @@ public class CreateFileActivity extends BaseActivity {
: ""; : "";
if (!AppUtil.hasNetworkConnection(appCtx)) { 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; return;
} }
if (((newFileName.isEmpty() || newFileContent.isEmpty()) if (((newFileName.isEmpty() || newFileContent.isEmpty())
&& fileAction != FILE_ACTION_DELETE) && fileAction != FILE_ACTION_DELETE)
|| newFileCommitMessage.isEmpty()) { || newFileCommitMessage.isEmpty()) {
Toasty.error(ctx, getString(R.string.newFileRequiredFields)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.newFileRequiredFields));
return; return;
} }
if (!AppUtil.checkStringsWithDash(newFileBranchName)) { if (!AppUtil.checkStringsWithDash(newFileBranchName)) {
Toasty.error(ctx, getString(R.string.newFileInvalidBranchName)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.newFileInvalidBranchName));
return; return;
} }
if (newFileCommitMessage.length() > 255) { if (newFileCommitMessage.length() > 255) {
Toasty.warning(ctx, getString(R.string.newFileCommitMessageError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.newFileCommitMessageError));
return; return;
} }
disableProcessButton();
switch (fileAction) { switch (fileAction) {
case FILE_ACTION_CREATE: case FILE_ACTION_CREATE:
createNewFile( createNewFile(
@ -264,39 +280,40 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) { switch (response.code()) {
case 201: case 201:
enableProcessButton(); SnackBar.success(
Toasty.success(ctx, getString(R.string.newFileSuccessMessage)); ctx,
findViewById(android.R.id.content),
getString(R.string.newFileSuccessMessage));
Intent result = new Intent(); Intent result = new Intent();
result.putExtra("fileModified", true); result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction); result.putExtra("fileAction", fileAction);
setResult(200, result); setResult(200, result);
RepoDetailActivity.updateFABActions = true; RepoDetailActivity.updateFABActions = true;
finish(); new Handler().postDelayed(() -> finish(), 3000);
break; break;
case 401: case 401:
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
break; break;
case 404: case 404:
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
break; break;
default: default:
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
break; break;
} }
} }
@Override @Override
public void onFailure(@NonNull Call<FileResponse> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<FileResponse> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
@ -332,9 +349,9 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) { switch (response.code()) {
case 200: case 200:
enableProcessButton(); SnackBar.success(
Toasty.info(
ctx, ctx,
findViewById(android.R.id.content),
getString( getString(
R.string.deleteFileMessage, R.string.deleteFileMessage,
repository.getBranchRef())); repository.getBranchRef()));
@ -342,33 +359,32 @@ public class CreateFileActivity extends BaseActivity {
result.putExtra("fileModified", true); result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction); result.putExtra("fileAction", fileAction);
setResult(200, result); setResult(200, result);
finish(); new Handler().postDelayed(() -> finish(), 3000);
break; break;
case 401: case 401:
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
break; break;
case 404: case 404:
enableProcessButton(); SnackBar.error(
Toasty.info(ctx, getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
break; break;
default: default:
enableProcessButton(); SnackBar.error(
Toasty.info(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
break; break;
} }
} }
@Override @Override
public void onFailure( public void onFailure(
@NonNull Call<FileDeleteResponse> call, @NonNull Throwable t) { @NonNull Call<FileDeleteResponse> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
@ -406,38 +422,39 @@ public class CreateFileActivity extends BaseActivity {
switch (response.code()) { switch (response.code()) {
case 200: case 200:
enableProcessButton(); SnackBar.success(
Toasty.info(ctx, getString(R.string.editFileMessage, branchName)); ctx,
findViewById(android.R.id.content),
getString(R.string.editFileMessage, branchName));
Intent result = new Intent(); Intent result = new Intent();
result.putExtra("fileModified", true); result.putExtra("fileModified", true);
result.putExtra("fileAction", fileAction); result.putExtra("fileAction", fileAction);
setResult(200, result); setResult(200, result);
finish(); new Handler().postDelayed(() -> finish(), 3000);
break; break;
case 401: case 401:
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
break; break;
case 404: case 404:
enableProcessButton(); SnackBar.error(
Toasty.info(ctx, getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
break; break;
default: default:
enableProcessButton(); SnackBar.error(
Toasty.info(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
break; break;
} }
} }
@Override @Override
public void onFailure(@NonNull Call<FileResponse> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<FileResponse> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
@ -468,27 +485,14 @@ public class CreateFileActivity extends BaseActivity {
binding.newFileBranches.setAdapter(adapter); binding.newFileBranches.setAdapter(adapter);
binding.newFileBranches.setText(repository.getBranchRef(), false); binding.newFileBranches.setText(repository.getBranchRef(), false);
enableProcessButton();
} }
} }
@Override @Override
public void onFailure(@NonNull Call<List<Branch>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Branch>> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
}
}); });
} }
private void disableProcessButton() {
binding.newFileCreate.setEnabled(false);
}
private void enableProcessButton() {
binding.newFileCreate.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,27 +1,37 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog; import android.app.Activity;
import android.content.Context; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.TextView; import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; 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.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; 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.CreateIssueOption;
import org.gitnex.tea4j.v2.models.Issue; import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.Label; 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.AssigneesActions;
import org.mian.gitnex.actions.LabelsActions; import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AssigneesListAdapter; import org.mian.gitnex.adapters.AssigneesListAdapter;
import org.mian.gitnex.adapters.AttachmentsAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter; import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateIssueBinding; import org.mian.gitnex.databinding.ActivityCreateIssueBinding;
import org.mian.gitnex.databinding.BottomSheetAttachmentsBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding; import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown; 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 org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -50,17 +63,15 @@ import retrofit2.Callback;
* @author M M Arif * @author M M Arif
*/ */
public class CreateIssueActivity extends BaseActivity public class CreateIssueActivity extends BaseActivity
implements View.OnClickListener, implements LabelsListAdapter.LabelsListAdapterListener,
LabelsListAdapter.LabelsListAdapterListener, AssigneesListAdapter.AssigneesListAdapterListener,
AssigneesListAdapter.AssigneesListAdapterListener { AttachmentsAdapter.AttachmentsReceiverListener {
private final List<Label> labelsList = new ArrayList<>(); private final List<Label> labelsList = new ArrayList<>();
private final LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>(); private final LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>();
private final List<User> assigneesList = new ArrayList<>(); private final List<User> assigneesList = new ArrayList<>();
private ActivityCreateIssueBinding viewBinding; private ActivityCreateIssueBinding viewBinding;
private View.OnClickListener onClickListener;
private int milestoneId; private int milestoneId;
private Date currentDate = null;
private RepositoryContext repository; private RepositoryContext repository;
private LabelsListAdapter labelsAdapter; private LabelsListAdapter labelsAdapter;
private AssigneesListAdapter assigneesAdapter; private AssigneesListAdapter assigneesAdapter;
@ -69,6 +80,9 @@ public class CreateIssueActivity extends BaseActivity
private List<String> assigneesListData = new ArrayList<>(); private List<String> assigneesListData = new ArrayList<>();
private boolean renderMd = false; private boolean renderMd = false;
private RepositoryContext repositoryContext; private RepositoryContext repositoryContext;
private static List<AttachmentsModel> attachmentsList;
private AttachmentsAdapter attachmentsAdapter;
private static final List<Uri> contentUri = new ArrayList<>();
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@Override @Override
@ -78,15 +92,9 @@ public class CreateIssueActivity extends BaseActivity
viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater()); viewBinding = ActivityCreateIssueBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot()); setContentView(viewBinding.getRoot());
setSupportActionBar(viewBinding.toolbar);
repositoryContext = RepositoryContext.fromIntent(getIntent()); repositoryContext = RepositoryContext.fromIntent(getIntent());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
materialAlertDialogBuilder = materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx, R.style.ThemeOverlay_Material3_Dialog_Alert); new MaterialAlertDialogBuilder(ctx, R.style.ThemeOverlay_Material3_Dialog_Alert);
@ -94,9 +102,10 @@ public class CreateIssueActivity extends BaseActivity
int resultLimit = Constants.getCurrentResultLimit(ctx); int resultLimit = Constants.getCurrentResultLimit(ctx);
viewBinding.newIssueTitle.requestFocus(); attachmentsList = new ArrayList<>();
assert imm != null; attachmentsAdapter = new AttachmentsAdapter(attachmentsList, ctx);
imm.showSoftInput(viewBinding.newIssueTitle, InputMethodManager.SHOW_IMPLICIT);
AttachmentsAdapter.setAttachmentsReceiveListener(this);
viewBinding.newIssueDescription.setOnTouchListener( viewBinding.newIssueDescription.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
@ -115,30 +124,62 @@ public class CreateIssueActivity extends BaseActivity
new AssigneesListAdapter( new AssigneesListAdapter(
ctx, assigneesList, CreateIssueActivity.this, assigneesListData); ctx, assigneesList, CreateIssueActivity.this, assigneesListData);
initCloseListener(); showDatePickerDialog();
viewBinding.close.setOnClickListener(onClickListener);
viewBinding.newIssueAssigneesList.setOnClickListener(this); viewBinding.newIssueDueDateLayout.setEndIconOnClickListener(
viewBinding.newIssueLabels.setOnClickListener(this); view -> viewBinding.newIssueDueDate.setText(""));
viewBinding.newIssueDueDate.setOnClickListener(this);
viewBinding.topAppBar.setNavigationOnClickListener(
v -> {
finish();
contentUri.clear();
});
viewBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
viewBinding.newIssueDescription
.getText())
.toString()),
viewBinding.markdownPreview,
repositoryContext);
viewBinding.markdownPreview.setVisibility(View.VISIBLE);
viewBinding.newIssueDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
viewBinding.markdownPreview.setVisibility(View.GONE);
viewBinding.newIssueDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else if (id == R.id.create) {
processNewIssue();
return true;
} else if (id == R.id.attachment) {
checkForAttachments();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
getMilestones(repository.getOwner(), repository.getName(), resultLimit); getMilestones(repository.getOwner(), repository.getName(), resultLimit);
disableProcessButton();
viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> showLabels()); viewBinding.newIssueLabels.setOnClickListener(newIssueLabels -> showLabels());
viewBinding.newIssueAssigneesList.setOnClickListener( viewBinding.newIssueAssigneesList.setOnClickListener(
newIssueAssigneesList -> showAssignees()); newIssueAssigneesList -> showAssignees());
if (!connToInternet) {
viewBinding.createNewIssueButton.setEnabled(false);
} else {
viewBinding.createNewIssueButton.setOnClickListener(this);
}
if (!repository.getPermissions().isPush()) { if (!repository.getPermissions().isPush()) {
viewBinding.newIssueAssigneesListLayout.setVisibility(View.GONE); viewBinding.newIssueAssigneesListLayout.setVisibility(View.GONE);
viewBinding.newIssueMilestoneSpinnerLayout.setVisibility(View.GONE); viewBinding.newIssueMilestoneSpinnerLayout.setVisibility(View.GONE);
@ -147,46 +188,148 @@ public class CreateIssueActivity extends BaseActivity
} }
} }
@Override ActivityResultLauncher<Intent> startActivityForResult =
public boolean onCreateOptionsMenu(@NonNull Menu menu) { registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
assert data != null;
contentUri.add(data.getData());
attachmentsList.add(
new AttachmentsModel(
AttachmentUtils.queryName(ctx, data.getData()),
data.getData()));
attachmentsAdapter.updateList(attachmentsList);
}
});
MenuInflater inflater = getMenuInflater(); public void onDestroy() {
inflater.inflate(R.menu.markdown_switcher, menu); AttachmentsAdapter.setAttachmentsReceiveListener(null);
super.onDestroy();
return true;
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public void setAttachmentsData(Uri filename) {
contentUri.remove(filename);
}
int id = item.getItemId(); private void checkForAttachments() {
if (id == R.id.markdown) { if (contentUri.size() > 0) {
if (!renderMd) { BottomSheetAttachmentsBinding bottomSheetAttachmentsBinding =
Markdown.render( BottomSheetAttachmentsBinding.inflate(getLayoutInflater());
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(viewBinding.newIssueDescription.getText())
.toString()),
viewBinding.markdownPreview,
repositoryContext);
viewBinding.markdownPreview.setVisibility(View.VISIBLE); BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ctx);
viewBinding.newIssueDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
viewBinding.markdownPreview.setVisibility(View.GONE);
viewBinding.newIssueDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true; bottomSheetAttachmentsBinding.addAttachment.setOnClickListener(
v1 -> openFileAttachmentActivity());
bottomSheetAttachmentsBinding.recyclerViewAttachments.setHasFixedSize(true);
bottomSheetAttachmentsBinding.recyclerViewAttachments.setLayoutManager(
new LinearLayoutManager(ctx));
bottomSheetAttachmentsBinding.recyclerViewAttachments.setAdapter(attachmentsAdapter);
bottomSheetDialog.setContentView(bottomSheetAttachmentsBinding.getRoot());
bottomSheetDialog.show();
} else { } else {
return super.onOptionsItemSelected(item); openFileAttachmentActivity();
} }
} }
private void openFileAttachmentActivity() {
Intent data = new Intent(Intent.ACTION_GET_CONTENT);
data.addCategory(Intent.CATEGORY_OPENABLE);
data.setType("*/*");
Intent intent = Intent.createChooser(data, "Choose a file");
startActivityForResult.launch(intent);
}
private void processAttachments(long issueIndex) {
for (int i = 0; i < contentUri.size(); i++) {
File file = AttachmentUtils.getFile(ctx, contentUri.get(i));
RequestBody requestFile =
RequestBody.create(
file,
MediaType.parse(
Objects.requireNonNull(
getContentResolver().getType(contentUri.get(i)))));
uploadAttachments(requestFile, issueIndex, file.getName());
}
}
private void uploadAttachments(RequestBody requestFile, long issueIndex, String filename1) {
Call<Attachment> call3 =
RetrofitClient.getApiInterface(ctx)
.issueCreateIssueAttachment(
requestFile,
repository.getOwner(),
repository.getName(),
issueIndex,
filename1);
call3.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<Attachment> call,
@NonNull retrofit2.Response<Attachment> response2) {
if (response2.code() == 201) {
new Handler().postDelayed(() -> finish(), 3000);
} else if (response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.attachmentsSaveError));
}
}
@Override
public void onFailure(@NonNull Call<Attachment> call, @NonNull Throwable t) {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
}
});
}
private void showDatePickerDialog() {
MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
builder.setSelection(Calendar.getInstance().getTimeInMillis());
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
viewBinding.newIssueDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
materialDatePicker.addOnPositiveButtonClickListener(
selection -> {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
String formattedDate = format.format(calendar.getTime());
viewBinding.newIssueDueDate.setText(formattedDate);
});
}
@Override @Override
public void assigneesInterface(List<String> data) { public void assigneesInterface(List<String> data) {
@ -255,8 +398,6 @@ public class CreateIssueActivity extends BaseActivity
private void processNewIssue() { private void processNewIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newIssueTitleForm = String newIssueTitleForm =
Objects.requireNonNull(viewBinding.newIssueTitle.getText()).toString(); Objects.requireNonNull(viewBinding.newIssueTitle.getText()).toString();
String newIssueDescriptionForm = String newIssueDescriptionForm =
@ -264,25 +405,20 @@ public class CreateIssueActivity extends BaseActivity
String newIssueDueDateForm = String newIssueDueDateForm =
Objects.requireNonNull(viewBinding.newIssueDueDate.getText()).toString(); Objects.requireNonNull(viewBinding.newIssueDueDate.getText()).toString();
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newIssueTitleForm.equals("")) { if (newIssueTitleForm.equals("")) {
Toasty.error(ctx, getString(R.string.issueTitleEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.issueTitleEmpty));
return; return;
} }
disableProcessButton();
createNewIssueFunc( createNewIssueFunc(
repository.getOwner(), repository.getOwner(),
repository.getName(), repository.getName(),
newIssueDescriptionForm, newIssueDescriptionForm,
milestoneId, milestoneId,
newIssueTitleForm); newIssueTitleForm,
newIssueDueDateForm);
} }
private void createNewIssueFunc( private void createNewIssueFunc(
@ -290,7 +426,8 @@ public class CreateIssueActivity extends BaseActivity
String repoName, String repoName,
String newIssueDescriptionForm, String newIssueDescriptionForm,
int newIssueMilestoneIdForm, int newIssueMilestoneIdForm,
String newIssueTitleForm) { String newIssueTitleForm,
String newIssueDueDateForm) {
ArrayList<Long> labelIds = new ArrayList<>(); ArrayList<Long> labelIds = new ArrayList<>();
for (Integer i : labelsIds) { for (Integer i : labelsIds) {
@ -300,7 +437,15 @@ public class CreateIssueActivity extends BaseActivity
CreateIssueOption createNewIssueJson = new CreateIssueOption(); CreateIssueOption createNewIssueJson = new CreateIssueOption();
createNewIssueJson.setBody(newIssueDescriptionForm); createNewIssueJson.setBody(newIssueDescriptionForm);
createNewIssueJson.setMilestone((long) newIssueMilestoneIdForm); createNewIssueJson.setMilestone((long) newIssueMilestoneIdForm);
createNewIssueJson.setDueDate(currentDate); String[] date = newIssueDueDateForm.split("-");
if (!newIssueDueDateForm.equalsIgnoreCase("")) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, Integer.parseInt(date[1]));
calendar.set(Calendar.DATE, Integer.parseInt(date[2]));
Date dueDate = calendar.getTime();
createNewIssueJson.setDueDate(dueDate);
}
createNewIssueJson.setTitle(newIssueTitleForm); createNewIssueJson.setTitle(newIssueTitleForm);
createNewIssueJson.setAssignees(assigneesListData); createNewIssueJson.setAssignees(assigneesListData);
createNewIssueJson.setLabels(labelIds); createNewIssueJson.setLabels(labelIds);
@ -320,37 +465,46 @@ public class CreateIssueActivity extends BaseActivity
if (response2.code() == 201) { if (response2.code() == 201) {
IssuesFragment.resumeIssues = true; IssuesFragment.resumeIssues = true;
Toasty.success(ctx, getString(R.string.issueCreated));
enableProcessButton();
RepoDetailActivity.updateRepo = true; RepoDetailActivity.updateRepo = true;
MainActivity.reloadRepos = true; MainActivity.reloadRepos = true;
finish();
SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.issueCreated));
assert response2.body() != null;
if (contentUri.size() > 0) {
processAttachments(response2.body().getNumber());
contentUri.clear();
} else {
new Handler().postDelayed(() -> finish(), 3000);
}
} else if (response2.code() == 401) { } else if (response2.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
Toasty.error(ctx, getString(R.string.genericError)); SnackBar.error(
enableProcessButton(); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError)); SnackBar.error(
enableProcessButton(); ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void getMilestones(String repoOwner, String repoName, int resultLimit) { private void getMilestones(String repoOwner, String repoName, int resultLimit) {
String msState = "open"; String msState = "open";
@ -396,7 +550,7 @@ public class CreateIssueActivity extends BaseActivity
new ArrayList<>(milestonesList.keySet())); new ArrayList<>(milestonesList.keySet()));
viewBinding.newIssueMilestoneSpinner.setAdapter(adapter); viewBinding.newIssueMilestoneSpinner.setAdapter(adapter);
enableProcessButton(); // enableProcessButton();
viewBinding.newIssueMilestoneSpinner.setOnItemClickListener( viewBinding.newIssueMilestoneSpinner.setOnItemClickListener(
(parent, view, position, id) -> { (parent, view, position, id) -> {
@ -422,53 +576,14 @@ public class CreateIssueActivity extends BaseActivity
public void onFailure( public void onFailure(
@NonNull Call<List<Milestone>> call, @NonNull Throwable t) { @NonNull Call<List<Milestone>> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
@Override
public void onClick(View v) {
if (v == viewBinding.newIssueDueDate) {
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
final int mMonth = c.get(Calendar.MONTH);
final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog =
new DatePickerDialog(
this,
(view, year, monthOfYear, dayOfMonth) -> {
viewBinding.newIssueDueDate.setText(
getString(
R.string.setDueDate,
year,
(monthOfYear + 1),
dayOfMonth));
currentDate = new Date(year - 1900, monthOfYear, dayOfMonth);
},
mYear,
mMonth,
mDay);
datePickerDialog.show();
} else if (v == viewBinding.createNewIssueButton) {
processNewIssue();
}
}
private void disableProcessButton() {
viewBinding.createNewIssueButton.setEnabled(false);
}
private void enableProcessButton() {
viewBinding.createNewIssueButton.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,15 +1,15 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.View; import android.view.MenuItem;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.pes.androidmaterialcolorpickerdialog.ColorPicker; import com.skydoves.colorpickerview.ColorPickerDialog;
import com.skydoves.colorpickerview.flag.BubbleFlag;
import com.skydoves.colorpickerview.listeners.ColorEnvelopeListener;
import com.skydoves.colorpickerview.preference.ColorPickerPreferenceManager;
import java.util.Objects; import java.util.Objects;
import org.gitnex.tea4j.v2.models.CreateLabelOption; import org.gitnex.tea4j.v2.models.CreateLabelOption;
import org.gitnex.tea4j.v2.models.EditLabelOption; import org.gitnex.tea4j.v2.models.EditLabelOption;
@ -19,7 +19,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateLabelBinding; import org.mian.gitnex.databinding.ActivityCreateLabelBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.RepositoryContext; import org.mian.gitnex.helpers.contexts.RepositoryContext;
import org.mian.gitnex.viewmodels.LabelsViewModel; import org.mian.gitnex.viewmodels.LabelsViewModel;
import org.mian.gitnex.viewmodels.OrganizationLabelsViewModel; import org.mian.gitnex.viewmodels.OrganizationLabelsViewModel;
@ -32,15 +32,11 @@ import retrofit2.Callback;
public class CreateLabelActivity extends BaseActivity { public class CreateLabelActivity extends BaseActivity {
public static boolean refreshLabels = false; public static boolean refreshLabels = false;
private ActivityCreateLabelBinding activityCreateLabelBinding; private ActivityCreateLabelBinding activityCreateLabelBinding;
private View.OnClickListener onClickListener;
private RepositoryContext repository; private RepositoryContext repository;
private String labelColor = ""; private String labelColor = "";
private final View.OnClickListener createLabelListener = v -> processCreateLabel();
private String labelColorDefault = ""; private String labelColorDefault = "";
private final View.OnClickListener updateLabelListener = v -> processUpdateLabel(); private ColorPickerPreferenceManager colorManager;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -50,9 +46,6 @@ public class CreateLabelActivity extends BaseActivity {
activityCreateLabelBinding = ActivityCreateLabelBinding.inflate(getLayoutInflater()); activityCreateLabelBinding = ActivityCreateLabelBinding.inflate(getLayoutInflater());
setContentView(activityCreateLabelBinding.getRoot()); setContentView(activityCreateLabelBinding.getRoot());
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
repository = RepositoryContext.fromIntent(getIntent()); repository = RepositoryContext.fromIntent(getIntent());
if (getIntent().getStringExtra("labelAction") != null if (getIntent().getStringExtra("labelAction") != null
@ -66,26 +59,18 @@ public class CreateLabelActivity extends BaseActivity {
return; return;
} }
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); activityCreateLabelBinding.topAppBar.setNavigationOnClickListener(v -> finish());
activityCreateLabelBinding.labelName.requestFocus(); colorManager = ColorPickerPreferenceManager.getInstance(this);
assert imm != null; colorManager.clearSavedAllData();
imm.showSoftInput(activityCreateLabelBinding.labelName, InputMethodManager.SHOW_IMPLICIT); activityCreateLabelBinding.colorPicker.setBackgroundColor(
colorManager.getColor("colorPickerDialogLabels", Color.RED));
final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33); MenuItem create = activityCreateLabelBinding.topAppBar.getMenu().getItem(0);
MenuItem update = activityCreateLabelBinding.topAppBar.getMenu().getItem(1);
update.setVisible(false);
initCloseListener(); activityCreateLabelBinding.colorPicker.setOnClickListener(v -> newColorPicker());
activityCreateLabelBinding.close.setOnClickListener(onClickListener);
activityCreateLabelBinding.colorPicker.setOnClickListener(v -> cp.show());
cp.setCallback(
color -> {
// Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color)));
activityCreateLabelBinding.colorPicker.setBackgroundColor(color);
labelColor = String.format("#%06X", (0xFFFFFF & color));
cp.dismiss();
});
if (getIntent().getStringExtra("labelAction") != null if (getIntent().getStringExtra("labelAction") != null
&& Objects.requireNonNull(getIntent().getStringExtra("labelAction")) && Objects.requireNonNull(getIntent().getStringExtra("labelAction"))
@ -96,28 +81,74 @@ public class CreateLabelActivity extends BaseActivity {
activityCreateLabelBinding.colorPicker.setBackgroundColor(labelColor_); activityCreateLabelBinding.colorPicker.setBackgroundColor(labelColor_);
labelColorDefault = "#" + getIntent().getStringExtra("labelColor"); labelColorDefault = "#" + getIntent().getStringExtra("labelColor");
TextView toolbar_title = activityCreateLabelBinding.toolbarTitle; activityCreateLabelBinding.topAppBar.setTitle(getString(R.string.pageTitleLabelUpdate));
toolbar_title.setText(getResources().getString(R.string.pageTitleLabelUpdate));
activityCreateLabelBinding.createLabelButton.setText( update.setVisible(true);
getResources().getString(R.string.newUpdateButtonCopy)); create.setVisible(false);
activityCreateLabelBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.update) {
processUpdateLabel();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
activityCreateLabelBinding.createLabelButton.setOnClickListener(updateLabelListener);
return; return;
} }
if (!connToInternet) { activityCreateLabelBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
activityCreateLabelBinding.createLabelButton.setEnabled(false); if (id == R.id.create) {
processCreateLabel();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
}
private void newColorPicker() {
ColorPickerDialog.Builder builder =
new ColorPickerDialog.Builder(this)
.setPreferenceName("colorPickerDialogLabels")
.setPositiveButton(
getString(R.string.okButton),
(ColorEnvelopeListener)
(envelope, clicked) -> {
activityCreateLabelBinding.colorPicker
.setBackgroundColor(envelope.getColor());
labelColor =
String.format(
"#%06X",
(0xFFFFFF & envelope.getColor()));
})
.attachAlphaSlideBar(true)
.attachBrightnessSlideBar(true)
.setBottomSpace(16);
builder.getColorPickerView().setFlagView(new BubbleFlag(this));
if (!labelColorDefault.equalsIgnoreCase("")) {
int labelColorCurrent = Color.parseColor(labelColorDefault);
builder.getColorPickerView().setInitialColor(labelColorCurrent);
} else { } else {
colorManager.setColor("colorPickerDialogLabels", Color.RED);
activityCreateLabelBinding.createLabelButton.setOnClickListener(createLabelListener);
} }
builder.getColorPickerView().setLifecycleOwner(this);
builder.show();
} }
private void processUpdateLabel() { private void processUpdateLabel() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String updateLabelName = String updateLabelName =
Objects.requireNonNull(activityCreateLabelBinding.labelName.getText()).toString(); Objects.requireNonNull(activityCreateLabelBinding.labelName.getText()).toString();
@ -130,25 +161,20 @@ public class CreateLabelActivity extends BaseActivity {
updateLabelColor = labelColor; updateLabelColor = labelColor;
} }
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (updateLabelName.equals("")) { if (updateLabelName.equals("")) {
Toasty.error(ctx, getString(R.string.labelEmptyError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.labelEmptyError));
return; return;
} }
if (!AppUtil.checkStrings(updateLabelName)) { if (!AppUtil.checkLabel(updateLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.labelNameError));
return; return;
} }
disableProcessButton();
patchLabel( patchLabel(
repository, repository,
updateLabelName, updateLabelName,
@ -158,8 +184,6 @@ public class CreateLabelActivity extends BaseActivity {
private void processCreateLabel() { private void processCreateLabel() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newLabelName = String newLabelName =
Objects.requireNonNull(activityCreateLabelBinding.labelName.getText()).toString(); Objects.requireNonNull(activityCreateLabelBinding.labelName.getText()).toString();
String newLabelColor; String newLabelColor;
@ -174,25 +198,20 @@ public class CreateLabelActivity extends BaseActivity {
newLabelColor = labelColor; newLabelColor = labelColor;
} }
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newLabelName.equals("")) { if (newLabelName.equals("")) {
Toasty.error(ctx, getString(R.string.labelEmptyError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.labelEmptyError));
return; return;
} }
if (!AppUtil.checkStrings(newLabelName)) { if (!AppUtil.checkLabel(newLabelName)) {
Toasty.error(ctx, getString(R.string.labelNameError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.labelNameError));
return; return;
} }
disableProcessButton();
createNewLabel(newLabelName, newLabelColor); createNewLabel(newLabelName, newLabelColor);
} }
@ -230,17 +249,21 @@ public class CreateLabelActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
Toasty.success(ctx, getString(R.string.labelCreated)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.labelCreated));
refreshLabels = true; refreshLabels = true;
finish(); new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@ -248,8 +271,6 @@ public class CreateLabelActivity extends BaseActivity {
public void onFailure(@NonNull Call<Label> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Label> call, @NonNull Throwable t) {
labelColor = ""; labelColor = "";
Log.e("onFailure", t.toString());
enableProcessButton();
} }
}); });
} }
@ -298,18 +319,22 @@ public class CreateLabelActivity extends BaseActivity {
if (response.code() == 200) { if (response.code() == 200) {
Toasty.success(ctx, getString(R.string.labelUpdated)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.labelUpdated));
refreshLabels = true; refreshLabels = true;
finish(); new Handler().postDelayed(() -> finish(), 3000);
} }
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@ -318,17 +343,10 @@ public class CreateLabelActivity extends BaseActivity {
labelColor = ""; labelColor = "";
labelColorDefault = ""; labelColorDefault = "";
Log.e("onFailure", t.toString());
enableProcessButton();
} }
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void deleteLabel(int labelId) { private void deleteLabel(int labelId) {
Call<Void> call; Call<Void> call;
@ -358,7 +376,11 @@ public class CreateLabelActivity extends BaseActivity {
if (response.code() == 204) { if (response.code() == 204) {
Toasty.success(ctx, getString(R.string.labelDeleteText)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.labelDeleteText));
if (getIntent().getStringExtra("type") != null if (getIntent().getStringExtra("type") != null
&& Objects.requireNonNull( && Objects.requireNonNull(
getIntent().getStringExtra("type")) getIntent().getStringExtra("type"))
@ -377,27 +399,18 @@ public class CreateLabelActivity extends BaseActivity {
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
Toasty.error(ctx, getString(R.string.genericError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
}
}); });
} }
private void disableProcessButton() {
activityCreateLabelBinding.createLabelButton.setEnabled(false);
}
private void enableProcessButton() {
activityCreateLabelBinding.createLabelButton.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,30 +1,28 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.android.material.datepicker.MaterialDatePicker;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone;
import org.gitnex.tea4j.v2.models.CreateMilestoneOption; import org.gitnex.tea4j.v2.models.CreateMilestoneOption;
import org.gitnex.tea4j.v2.models.Milestone; import org.gitnex.tea4j.v2.models.Milestone;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateMilestoneBinding; import org.mian.gitnex.databinding.ActivityCreateMilestoneBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.RepositoryContext; import org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -32,13 +30,10 @@ import retrofit2.Callback;
/** /**
* @author M M Arif * @author M M Arif
*/ */
public class CreateMilestoneActivity extends BaseActivity implements View.OnClickListener { public class CreateMilestoneActivity extends BaseActivity {
private ActivityCreateMilestoneBinding binding; private ActivityCreateMilestoneBinding binding;
private View.OnClickListener onClickListener;
private RepositoryContext repository; private RepositoryContext repository;
private Date currentDate = null;
private final View.OnClickListener createMilestoneListener = v -> processNewMilestone();
private boolean renderMd = false; private boolean renderMd = false;
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@ -49,18 +44,15 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
binding = ActivityCreateMilestoneBinding.inflate(getLayoutInflater()); binding = ActivityCreateMilestoneBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
repository = RepositoryContext.fromIntent(getIntent()); repository = RepositoryContext.fromIntent(getIntent());
binding.milestoneTitle.requestFocus(); binding.topAppBar.setNavigationOnClickListener(v -> finish());
assert imm != null;
imm.showSoftInput(binding.milestoneTitle, InputMethodManager.SHOW_IMPLICIT); MenuItem attachment = binding.topAppBar.getMenu().getItem(0);
attachment.setVisible(false);
showDatePickerDialog();
binding.milestoneDescription.setOnTouchListener( binding.milestoneDescription.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
@ -74,78 +66,79 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
return false; return false;
}); });
initCloseListener(); binding.topAppBar.setOnMenuItemClickListener(
binding.close.setOnClickListener(onClickListener); menuItem -> {
binding.milestoneDueDate.setOnClickListener(this); int id = menuItem.getItemId();
if (!connToInternet) { if (id == R.id.markdown) {
binding.createNewMilestoneButton.setEnabled(false); if (!renderMd) {
} else { Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
Objects.requireNonNull(
binding.milestoneDescription
.getText())
.toString())),
binding.markdownPreview);
binding.createNewMilestoneButton.setOnClickListener(createMilestoneListener); binding.markdownPreview.setVisibility(View.VISIBLE);
} binding.milestoneDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.milestoneDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else if (id == R.id.create) {
processNewMilestone();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
} }
@Override private void showDatePickerDialog() {
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
MenuInflater inflater = getMenuInflater(); MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
inflater.inflate(R.menu.markdown_switcher, menu); builder.setSelection(Calendar.getInstance().getTimeInMillis());
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
return true; binding.milestoneDueDate.setOnClickListener(
} v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
@Override materialDatePicker.addOnPositiveButtonClickListener(
public boolean onOptionsItemSelected(MenuItem item) { selection -> {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
int id = item.getItemId(); calendar.setTimeInMillis(selection);
SimpleDateFormat format =
if (id == R.id.markdown) { new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
if (!renderMd) { String formattedDate = format.format(calendar.getTime());
Markdown.render( binding.milestoneDueDate.setText(formattedDate);
ctx, });
EmojiParser.parseToUnicode(
Objects.requireNonNull(
Objects.requireNonNull(
binding.milestoneDescription.getText())
.toString())),
binding.markdownPreview);
binding.markdownPreview.setVisibility(View.VISIBLE);
binding.milestoneDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.milestoneDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
} }
private void processNewMilestone() { private void processNewMilestone() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newMilestoneTitle = String newMilestoneTitle =
Objects.requireNonNull(binding.milestoneTitle.getText()).toString(); Objects.requireNonNull(binding.milestoneTitle.getText()).toString();
String newMilestoneDescription = String newMilestoneDescription =
Objects.requireNonNull(binding.milestoneDescription.getText()).toString(); Objects.requireNonNull(binding.milestoneDescription.getText()).toString();
String milestoneDueDate =
if (!connToInternet) { Objects.requireNonNull(binding.milestoneDueDate.getText()).toString();
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newMilestoneTitle.equals("")) { if (newMilestoneTitle.equals("")) {
Toasty.error(ctx, getString(R.string.milestoneNameErrorEmpty)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.milestoneNameErrorEmpty));
return; return;
} }
@ -153,29 +146,41 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if (newMilestoneDescription.length() > 255) { if (newMilestoneDescription.length() > 255) {
Toasty.warning(ctx, getString(R.string.milestoneDescError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.milestoneDescError));
return; return;
} }
} }
disableProcessButton();
createNewMilestone( createNewMilestone(
repository.getOwner(), repository.getOwner(),
repository.getName(), repository.getName(),
newMilestoneTitle, newMilestoneTitle,
newMilestoneDescription); newMilestoneDescription,
milestoneDueDate);
} }
private void createNewMilestone( private void createNewMilestone(
String repoOwner, String repoOwner,
String repoName, String repoName,
String newMilestoneTitle, String newMilestoneTitle,
String newMilestoneDescription) { String newMilestoneDescription,
String milestoneDueDate) {
CreateMilestoneOption createMilestone = new CreateMilestoneOption(); CreateMilestoneOption createMilestone = new CreateMilestoneOption();
createMilestone.setDescription(newMilestoneDescription); createMilestone.setDescription(newMilestoneDescription);
createMilestone.setTitle(newMilestoneTitle); createMilestone.setTitle(newMilestoneTitle);
createMilestone.setDueOn(currentDate); String[] date = milestoneDueDate.split("-");
if (!milestoneDueDate.equalsIgnoreCase("")) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, Integer.parseInt(date[1]));
calendar.set(Calendar.DATE, Integer.parseInt(date[2]));
Date dueDate = calendar.getTime();
createMilestone.setDueOn(dueDate);
}
Call<Milestone> call; Call<Milestone> call;
@ -184,7 +189,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
.issueCreateMilestone(repoOwner, repoName, createMilestone); .issueCreateMilestone(repoOwner, repoName, createMilestone);
call.enqueue( call.enqueue(
new Callback<Milestone>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -196,74 +201,30 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
if (response.code() == 201) { if (response.code() == 201) {
RepoDetailActivity.updateFABActions = true; RepoDetailActivity.updateFABActions = true;
Toasty.success(ctx, getString(R.string.milestoneCreated)); SnackBar.success(
enableProcessButton(); ctx,
finish(); findViewById(android.R.id.content),
getString(R.string.milestoneCreated));
new Handler().postDelayed(() -> finish(), 3000);
} }
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Milestone> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Milestone> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
@Override
public void onClick(View v) {
if (v == binding.milestoneDueDate) {
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
final int mMonth = c.get(Calendar.MONTH);
final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog =
new DatePickerDialog(
this,
(view, year, monthOfYear, dayOfMonth) -> {
binding.milestoneDueDate.setText(
getString(
R.string.setDueDate,
year,
(monthOfYear + 1),
dayOfMonth));
currentDate = new Date(year - 1900, monthOfYear, dayOfMonth);
},
mYear,
mMonth,
mDay);
datePickerDialog.show();
}
}
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
binding.createNewMilestoneButton.setEnabled(false);
}
private void enableProcessButton() {
binding.createNewMilestoneButton.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,15 +1,11 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.util.Patterns; import android.util.Patterns;
import android.view.View; import android.view.MenuItem;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.Objects;
import org.gitnex.tea4j.v2.models.CreateUserOption; import org.gitnex.tea4j.v2.models.CreateUserOption;
import org.gitnex.tea4j.v2.models.User; import org.gitnex.tea4j.v2.models.User;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -17,7 +13,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateNewUserBinding; import org.mian.gitnex.databinding.ActivityCreateNewUserBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -26,93 +22,91 @@ import retrofit2.Callback;
*/ */
public class CreateNewUserActivity extends BaseActivity { public class CreateNewUserActivity extends BaseActivity {
private View.OnClickListener onClickListener; private ActivityCreateNewUserBinding activityCreateNewUserBinding;
private EditText fullName;
private EditText userUserName;
private EditText userEmail;
private EditText userPassword;
private Button createUserButton;
private final View.OnClickListener createNewUserListener = v -> processCreateNewUser();
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ActivityCreateNewUserBinding activityCreateNewUserBinding = activityCreateNewUserBinding = ActivityCreateNewUserBinding.inflate(getLayoutInflater());
ActivityCreateNewUserBinding.inflate(getLayoutInflater());
setContentView(activityCreateNewUserBinding.getRoot()); setContentView(activityCreateNewUserBinding.getRoot());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); activityCreateNewUserBinding.topAppBar.setNavigationOnClickListener(
v -> {
finish();
});
InputMethodManager imm = MenuItem attachment = activityCreateNewUserBinding.topAppBar.getMenu().getItem(0);
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); MenuItem markdown = activityCreateNewUserBinding.topAppBar.getMenu().getItem(1);
attachment.setVisible(false);
markdown.setVisible(false);
ImageView closeActivity = activityCreateNewUserBinding.close; activityCreateNewUserBinding.topAppBar.setOnMenuItemClickListener(
createUserButton = activityCreateNewUserBinding.createUserButton; menuItem -> {
fullName = activityCreateNewUserBinding.fullName; int id = menuItem.getItemId();
userUserName = activityCreateNewUserBinding.userUserName;
userEmail = activityCreateNewUserBinding.userEmail;
userPassword = activityCreateNewUserBinding.userPassword;
fullName.requestFocus(); if (id == R.id.create) {
assert imm != null; processCreateNewUser();
imm.showSoftInput(fullName, InputMethodManager.SHOW_IMPLICIT); return true;
} else {
initCloseListener(); return super.onOptionsItemSelected(menuItem);
closeActivity.setOnClickListener(onClickListener); }
});
if (!connToInternet) {
disableProcessButton();
} else {
createUserButton.setOnClickListener(createNewUserListener);
}
} }
private void processCreateNewUser() { private void processCreateNewUser() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); String newFullName =
Objects.requireNonNull(activityCreateNewUserBinding.fullName.getText())
String newFullName = fullName.getText().toString().trim(); .toString()
String newUserName = userUserName.getText().toString().trim(); .trim();
String newUserEmail = userEmail.getText().toString().trim(); String newUserName =
String newUserPassword = userPassword.getText().toString(); Objects.requireNonNull(activityCreateNewUserBinding.userUserName.getText())
.toString()
if (!connToInternet) { .trim();
String newUserEmail =
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Objects.requireNonNull(activityCreateNewUserBinding.userEmail.getText())
return; .toString()
} .trim();
String newUserPassword =
Objects.requireNonNull(activityCreateNewUserBinding.userPassword.getText())
.toString();
if (newFullName.equals("") if (newFullName.equals("")
|| newUserName.equals("") | newUserEmail.equals("") || newUserName.equals("") | newUserEmail.equals("")
|| newUserPassword.equals("")) { || newUserPassword.equals("")) {
Toasty.error(ctx, getString(R.string.emptyFields)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.emptyFields));
return; return;
} }
if (!AppUtil.checkStrings(newFullName)) { if (!AppUtil.checkStrings(newFullName)) {
Toasty.error(ctx, getString(R.string.userInvalidFullName)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.userInvalidFullName));
return; return;
} }
if (!AppUtil.checkStringsWithAlphaNumeric(newUserName)) { if (!AppUtil.checkStringsWithAlphaNumeric(newUserName)) {
Toasty.error(ctx, getString(R.string.userInvalidUserName)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.userInvalidUserName));
return; return;
} }
if (!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) { if (!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
Toasty.error(ctx, getString(R.string.userInvalidEmail)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.userInvalidEmail));
return; return;
} }
disableProcessButton();
createNewUser(newFullName, newUserName, newUserEmail, newUserPassword); createNewUser(newFullName, newUserName, newUserEmail, newUserPassword);
} }
@ -129,7 +123,7 @@ public class CreateNewUserActivity extends BaseActivity {
Call<User> call = RetrofitClient.getApiInterface(ctx).adminCreateUser(createUser); Call<User> call = RetrofitClient.getApiInterface(ctx).adminCreateUser(createUser);
call.enqueue( call.enqueue(
new Callback<User>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -137,53 +131,43 @@ public class CreateNewUserActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
Toasty.success(ctx, getString(R.string.userCreatedText)); SnackBar.success(
enableProcessButton(); ctx,
finish(); findViewById(android.R.id.content),
getString(R.string.userCreatedText));
new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 403) { } else if (response.code() == 403) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); ctx,
findViewById(android.R.id.content),
getString(R.string.authorizeError));
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else if (response.code() == 422) { } else if (response.code() == 422) {
enableProcessButton(); SnackBar.warning(
Toasty.warning(ctx, ctx.getString(R.string.userExistsError)); ctx,
findViewById(android.R.id.content),
getString(R.string.userExistsError));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
createUserButton.setEnabled(false);
}
private void enableProcessButton() {
createUserButton.setEnabled(true);
}
} }

View File

@ -1,16 +1,12 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.Objects;
import org.gitnex.tea4j.v2.models.CreateOrgOption; import org.gitnex.tea4j.v2.models.CreateOrgOption;
import org.gitnex.tea4j.v2.models.Organization; import org.gitnex.tea4j.v2.models.Organization;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -19,7 +15,7 @@ import org.mian.gitnex.databinding.ActivityCreateOrganizationBinding;
import org.mian.gitnex.fragments.OrganizationsFragment; import org.mian.gitnex.fragments.OrganizationsFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -28,13 +24,7 @@ import retrofit2.Callback;
*/ */
public class CreateOrganizationActivity extends BaseActivity { public class CreateOrganizationActivity extends BaseActivity {
public ImageView closeActivity; private ActivityCreateOrganizationBinding activityCreateOrganizationBinding;
private View.OnClickListener onClickListener;
private Button createOrganizationButton;
private EditText orgName;
private EditText orgDesc;
private final View.OnClickListener createOrgListener = v -> processNewOrganization();
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@Override @Override
@ -42,24 +32,18 @@ public class CreateOrganizationActivity extends BaseActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ActivityCreateOrganizationBinding activityCreateOrganizationBinding = activityCreateOrganizationBinding =
ActivityCreateOrganizationBinding.inflate(getLayoutInflater()); ActivityCreateOrganizationBinding.inflate(getLayoutInflater());
setContentView(activityCreateOrganizationBinding.getRoot()); setContentView(activityCreateOrganizationBinding.getRoot());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); MenuItem attachment = activityCreateOrganizationBinding.topAppBar.getMenu().getItem(0);
MenuItem markdown = activityCreateOrganizationBinding.topAppBar.getMenu().getItem(1);
attachment.setVisible(false);
markdown.setVisible(false);
InputMethodManager imm = activityCreateOrganizationBinding.topAppBar.setNavigationOnClickListener(v -> finish());
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = activityCreateOrganizationBinding.close; activityCreateOrganizationBinding.newOrganizationDescription.setOnTouchListener(
orgName = activityCreateOrganizationBinding.newOrganizationName;
orgDesc = activityCreateOrganizationBinding.newOrganizationDescription;
orgName.requestFocus();
assert imm != null;
imm.showSoftInput(orgName, InputMethodManager.SHOW_IMPLICIT);
orgDesc.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
touchView.getParent().requestDisallowInterceptTouchEvent(true); touchView.getParent().requestDisallowInterceptTouchEvent(true);
@ -71,56 +55,53 @@ public class CreateOrganizationActivity extends BaseActivity {
return false; return false;
}); });
initCloseListener(); activityCreateOrganizationBinding.topAppBar.setOnMenuItemClickListener(
closeActivity.setOnClickListener(onClickListener); menuItem -> {
int id = menuItem.getItemId();
createOrganizationButton = activityCreateOrganizationBinding.createNewOrganizationButton; if (id == R.id.create) {
processNewOrganization();
if (!connToInternet) { return true;
} else {
createOrganizationButton.setEnabled(false); return super.onOptionsItemSelected(menuItem);
} else { }
});
createOrganizationButton.setOnClickListener(createOrgListener);
}
}
private void initCloseListener() {
onClickListener = view -> finish();
} }
private void processNewOrganization() { private void processNewOrganization() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); String newOrgName =
Objects.requireNonNull(
String newOrgName = orgName.getText().toString(); activityCreateOrganizationBinding.newOrganizationName.getText())
String newOrgDesc = orgDesc.getText().toString(); .toString();
String newOrgDesc =
if (!connToInternet) { Objects.requireNonNull(
activityCreateOrganizationBinding.newOrganizationDescription
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); .getText())
return; .toString();
}
if (!newOrgDesc.equals("")) { if (!newOrgDesc.equals("")) {
if (newOrgDesc.length() > 255) { if (newOrgDesc.length() > 255) {
Toasty.warning(ctx, getString(R.string.orgDescError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.orgDescError));
return; return;
} }
} }
if (newOrgName.equals("")) { if (newOrgName.equals("")) {
Toasty.error(ctx, getString(R.string.orgNameErrorEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.orgNameErrorEmpty));
} else if (!AppUtil.checkStrings(newOrgName)) { } else if (!AppUtil.checkStrings(newOrgName)) {
Toasty.warning(ctx, getString(R.string.orgNameErrorInvalid)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.orgNameErrorInvalid));
} else { } else {
disableProcessButton();
createNewOrganization(newOrgName, newOrgDesc); createNewOrganization(newOrgName, newOrgDesc);
} }
} }
@ -134,7 +115,7 @@ public class CreateOrganizationActivity extends BaseActivity {
Call<Organization> call = RetrofitClient.getApiInterface(ctx).orgCreate(createOrganization); Call<Organization> call = RetrofitClient.getApiInterface(ctx).orgCreate(createOrganization);
call.enqueue( call.enqueue(
new Callback<Organization>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -143,51 +124,46 @@ public class CreateOrganizationActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
OrganizationsFragment.orgCreated = true; OrganizationsFragment.orgCreated = true;
enableProcessButton(); SnackBar.success(
Toasty.success(ctx, getString(R.string.orgCreated)); ctx,
finish(); findViewById(android.R.id.content),
getString(R.string.orgCreated));
new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 409) { } else if (response.code() == 409) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.orgExistsError)); ctx,
findViewById(android.R.id.content),
getString(R.string.orgExistsError));
} else if (response.code() == 422) { } else if (response.code() == 422) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.orgExistsError)); ctx,
findViewById(android.R.id.content),
getString(R.string.orgExistsError));
} else { } else {
if (response.code() == 404) { if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Organization> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Organization> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void disableProcessButton() {
createOrganizationButton.setEnabled(false);
}
private void enableProcessButton() {
createOrganizationButton.setEnabled(true);
}
} }

View File

@ -1,26 +1,37 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog; import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; 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.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; 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.Branch; import org.gitnex.tea4j.v2.models.Branch;
import org.gitnex.tea4j.v2.models.CreatePullRequestOption; import org.gitnex.tea4j.v2.models.CreatePullRequestOption;
import org.gitnex.tea4j.v2.models.Label; import org.gitnex.tea4j.v2.models.Label;
@ -28,14 +39,19 @@ import org.gitnex.tea4j.v2.models.Milestone;
import org.gitnex.tea4j.v2.models.PullRequest; import org.gitnex.tea4j.v2.models.PullRequest;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.actions.LabelsActions; import org.mian.gitnex.actions.LabelsActions;
import org.mian.gitnex.adapters.AttachmentsAdapter;
import org.mian.gitnex.adapters.LabelsListAdapter; import org.mian.gitnex.adapters.LabelsListAdapter;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreatePrBinding; import org.mian.gitnex.databinding.ActivityCreatePrBinding;
import org.mian.gitnex.databinding.BottomSheetAttachmentsBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown; 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 org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -44,22 +60,24 @@ import retrofit2.Callback;
* @author M M Arif * @author M M Arif
*/ */
public class CreatePullRequestActivity extends BaseActivity public class CreatePullRequestActivity extends BaseActivity
implements LabelsListAdapter.LabelsListAdapterListener { implements LabelsListAdapter.LabelsListAdapterListener,
AttachmentsAdapter.AttachmentsReceiverListener {
private final List<String> assignees = new ArrayList<>(); private final List<String> assignees = new ArrayList<>();
LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>(); LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>();
List<String> branchesList = new ArrayList<>(); List<String> branchesList = new ArrayList<>();
List<Label> labelsList = new ArrayList<>(); List<Label> labelsList = new ArrayList<>();
private View.OnClickListener onClickListener;
private ActivityCreatePrBinding viewBinding; private ActivityCreatePrBinding viewBinding;
private List<Integer> labelsIds = new ArrayList<>(); private List<Integer> labelsIds = new ArrayList<>();
private int milestoneId; private int milestoneId;
private Date currentDate = null;
private RepositoryContext repository; private RepositoryContext repository;
private LabelsListAdapter labelsAdapter; private LabelsListAdapter labelsAdapter;
private MaterialAlertDialogBuilder materialAlertDialogBuilder; private MaterialAlertDialogBuilder materialAlertDialogBuilder;
private boolean renderMd = false; private boolean renderMd = false;
private RepositoryContext repositoryContext; private RepositoryContext repositoryContext;
private static List<AttachmentsModel> attachmentsList;
private AttachmentsAdapter attachmentsAdapter;
private static final List<Uri> contentUri = new ArrayList<>();
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@Override @Override
@ -69,7 +87,6 @@ public class CreatePullRequestActivity extends BaseActivity
viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater()); viewBinding = ActivityCreatePrBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot()); setContentView(viewBinding.getRoot());
setSupportActionBar(viewBinding.toolbar);
repositoryContext = RepositoryContext.fromIntent(getIntent()); repositoryContext = RepositoryContext.fromIntent(getIntent());
@ -78,6 +95,11 @@ public class CreatePullRequestActivity extends BaseActivity
repository = RepositoryContext.fromIntent(getIntent()); repository = RepositoryContext.fromIntent(getIntent());
attachmentsList = new ArrayList<>();
attachmentsAdapter = new AttachmentsAdapter(attachmentsList, ctx);
AttachmentsAdapter.setAttachmentsReceiveListener(this);
int resultLimit = Constants.getCurrentResultLimit(ctx); int resultLimit = Constants.getCurrentResultLimit(ctx);
viewBinding.prBody.setOnTouchListener( viewBinding.prBody.setOnTouchListener(
@ -95,22 +117,55 @@ public class CreatePullRequestActivity extends BaseActivity
labelsAdapter = labelsAdapter =
new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds); new LabelsListAdapter(labelsList, CreatePullRequestActivity.this, labelsIds);
ImageView closeActivity = findViewById(R.id.close); showDatePickerDialog();
initCloseListener(); viewBinding.topAppBar.setNavigationOnClickListener(
closeActivity.setOnClickListener(onClickListener); v -> {
finish();
contentUri.clear();
});
viewBinding.prDueDate.setOnClickListener(dueDate -> setDueDate()); viewBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
disableProcessButton(); if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(viewBinding.prBody.getText())
.toString()),
viewBinding.markdownPreview,
repositoryContext);
viewBinding.markdownPreview.setVisibility(View.VISIBLE);
viewBinding.prBodyLayout.setVisibility(View.GONE);
renderMd = true;
} else {
viewBinding.markdownPreview.setVisibility(View.GONE);
viewBinding.prBodyLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else if (id == R.id.create) {
processPullRequest();
return true;
} else if (id == R.id.attachment) {
checkForAttachments();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
getMilestones(repository.getOwner(), repository.getName(), resultLimit); getMilestones(repository.getOwner(), repository.getName(), resultLimit);
getBranches(repository.getOwner(), repository.getName()); getBranches(repository.getOwner(), repository.getName());
viewBinding.prLabels.setOnClickListener(prLabels -> showLabels()); viewBinding.prLabels.setOnClickListener(prLabels -> showLabels());
viewBinding.createPr.setOnClickListener(createPr -> processPullRequest());
if (!repository.getPermissions().isPush()) { if (!repository.getPermissions().isPush()) {
viewBinding.prDueDateLayout.setVisibility(View.GONE); viewBinding.prDueDateLayout.setVisibility(View.GONE);
viewBinding.prLabelsLayout.setVisibility(View.GONE); viewBinding.prLabelsLayout.setVisibility(View.GONE);
@ -118,51 +173,130 @@ public class CreatePullRequestActivity extends BaseActivity
} }
} }
@Override ActivityResultLauncher<Intent> startActivityForResult =
public boolean onCreateOptionsMenu(@NonNull Menu menu) { registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
assert data != null;
contentUri.add(data.getData());
attachmentsList.add(
new AttachmentsModel(
AttachmentUtils.queryName(ctx, data.getData()),
data.getData()));
attachmentsAdapter.updateList(attachmentsList);
}
});
MenuInflater inflater = getMenuInflater(); public void onDestroy() {
inflater.inflate(R.menu.markdown_switcher, menu); AttachmentsAdapter.setAttachmentsReceiveListener(null);
super.onDestroy();
return true;
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public void setAttachmentsData(Uri filename) {
contentUri.remove(filename);
}
int id = item.getItemId(); private void checkForAttachments() {
if (id == R.id.markdown) { if (contentUri.size() > 0) {
if (!renderMd) { BottomSheetAttachmentsBinding bottomSheetAttachmentsBinding =
Markdown.render( BottomSheetAttachmentsBinding.inflate(getLayoutInflater());
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(viewBinding.prBody.getText()).toString()),
viewBinding.markdownPreview,
repositoryContext);
viewBinding.markdownPreview.setVisibility(View.VISIBLE); BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ctx);
viewBinding.prBodyLayout.setVisibility(View.GONE);
renderMd = true;
} else {
viewBinding.markdownPreview.setVisibility(View.GONE);
viewBinding.prBodyLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true; bottomSheetAttachmentsBinding.addAttachment.setOnClickListener(
v1 -> openFileAttachmentActivity());
bottomSheetAttachmentsBinding.recyclerViewAttachments.setHasFixedSize(true);
bottomSheetAttachmentsBinding.recyclerViewAttachments.setLayoutManager(
new LinearLayoutManager(ctx));
bottomSheetAttachmentsBinding.recyclerViewAttachments.setAdapter(attachmentsAdapter);
bottomSheetDialog.setContentView(bottomSheetAttachmentsBinding.getRoot());
bottomSheetDialog.show();
} else { } else {
return super.onOptionsItemSelected(item); openFileAttachmentActivity();
} }
} }
private void openFileAttachmentActivity() {
Intent data = new Intent(Intent.ACTION_GET_CONTENT);
data.addCategory(Intent.CATEGORY_OPENABLE);
data.setType("*/*");
Intent intent = Intent.createChooser(data, "Choose a file");
startActivityForResult.launch(intent);
}
private void processAttachments(long issueIndex) {
for (int i = 0; i < contentUri.size(); i++) {
File file = AttachmentUtils.getFile(ctx, contentUri.get(i));
RequestBody requestFile =
RequestBody.create(
file, MediaType.parse(getContentResolver().getType(contentUri.get(i))));
uploadAttachments(requestFile, issueIndex, file.getName());
}
}
private void uploadAttachments(RequestBody requestFile, long issueIndex, String filename1) {
Call<Attachment> call3 =
RetrofitClient.getApiInterface(ctx)
.issueCreateIssueAttachment(
requestFile,
repository.getOwner(),
repository.getName(),
issueIndex,
filename1);
call3.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<Attachment> call,
@NonNull retrofit2.Response<Attachment> response2) {
if (response2.code() == 201) {
new Handler().postDelayed(() -> finish(), 3000);
} else if (response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.attachmentsSaveError));
}
}
@Override
public void onFailure(@NonNull Call<Attachment> call, @NonNull Throwable t) {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
}
});
}
private void processPullRequest() { private void processPullRequest() {
String prTitle = String.valueOf(viewBinding.prTitle.getText()); String prTitle = String.valueOf(viewBinding.prTitle.getText());
String prDescription = String.valueOf(viewBinding.prBody.getText()); String prDescription = String.valueOf(viewBinding.prBody.getText());
String mergeInto = viewBinding.mergeIntoBranchSpinner.getText().toString(); String mergeInto = viewBinding.mergeIntoBranchSpinner.getText().toString();
String pullFrom = viewBinding.pullFromBranchSpinner.getText().toString(); String pullFrom = viewBinding.pullFromBranchSpinner.getText().toString();
String prDueDate = Objects.requireNonNull(viewBinding.prDueDate.getText()).toString();
assignees.add(""); assignees.add("");
@ -173,19 +307,23 @@ public class CreatePullRequestActivity extends BaseActivity
if (prTitle.matches("")) { if (prTitle.matches("")) {
Toasty.error(ctx, getString(R.string.titleError)); SnackBar.error(ctx, findViewById(android.R.id.content), getString(R.string.titleError));
} else if (mergeInto.matches("")) { } else if (mergeInto.matches("")) {
Toasty.error(ctx, getString(R.string.mergeIntoError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.mergeIntoError));
} else if (pullFrom.matches("")) { } else if (pullFrom.matches("")) {
Toasty.error(ctx, getString(R.string.pullFromError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.pullFromError));
} else if (pullFrom.equals(mergeInto)) { } else if (pullFrom.equals(mergeInto)) {
Toasty.error(ctx, getString(R.string.sameBranchesError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.sameBranchesError));
} else { } else {
createPullRequest(prTitle, prDescription, mergeInto, pullFrom, milestoneId, assignees); createPullRequest(
prTitle, prDescription, mergeInto, pullFrom, milestoneId, assignees, prDueDate);
} }
} }
@ -195,7 +333,8 @@ public class CreatePullRequestActivity extends BaseActivity
String mergeInto, String mergeInto,
String pullFrom, String pullFrom,
int milestoneId, int milestoneId,
List<String> assignees) { List<String> assignees,
String prDueDate) {
ArrayList<Long> labelIds = new ArrayList<>(); ArrayList<Long> labelIds = new ArrayList<>();
for (Integer i : labelsIds) { for (Integer i : labelsIds) {
@ -210,7 +349,15 @@ public class CreatePullRequestActivity extends BaseActivity
createPullRequest.setBase(mergeInto); createPullRequest.setBase(mergeInto);
createPullRequest.setHead(pullFrom); createPullRequest.setHead(pullFrom);
createPullRequest.setLabels(labelIds); createPullRequest.setLabels(labelIds);
createPullRequest.setDueDate(currentDate); String[] date = prDueDate.split("-");
if (!prDueDate.equalsIgnoreCase("")) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, Integer.parseInt(date[1]));
calendar.set(Calendar.DATE, Integer.parseInt(date[2]));
Date dueDate = calendar.getTime();
createPullRequest.setDueDate(dueDate);
}
Call<PullRequest> transferCall = Call<PullRequest> transferCall =
RetrofitClient.getApiInterface(ctx) RetrofitClient.getApiInterface(ctx)
@ -225,40 +372,78 @@ public class CreatePullRequestActivity extends BaseActivity
@NonNull Call<PullRequest> call, @NonNull Call<PullRequest> call,
@NonNull retrofit2.Response<PullRequest> response) { @NonNull retrofit2.Response<PullRequest> response) {
disableProcessButton();
if (response.code() == 201) { if (response.code() == 201) {
Toasty.success(ctx, getString(R.string.prCreateSuccess)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.prCreateSuccess));
RepoDetailActivity.updateRepo = true; RepoDetailActivity.updateRepo = true;
PullRequestsFragment.resumePullRequests = true; PullRequestsFragment.resumePullRequests = true;
MainActivity.reloadRepos = true; MainActivity.reloadRepos = true;
finish();
if (contentUri.size() > 0) {
assert response.body() != null;
processAttachments(response.body().getNumber());
contentUri.clear();
} else {
new Handler().postDelayed(() -> finish(), 3000);
}
} else if (response.code() == 409 } else if (response.code() == 409
|| response.message().equals("Conflict")) { || response.message().equals("Conflict")) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.prAlreadyExists)); ctx,
findViewById(android.R.id.content),
getString(R.string.prAlreadyExists));
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<PullRequest> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<PullRequest> call, @NonNull Throwable t) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericServerResponseError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
private void showDatePickerDialog() {
MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
builder.setSelection(Calendar.getInstance().getTimeInMillis());
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
viewBinding.prDueDate.setOnClickListener(
v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
materialDatePicker.addOnPositiveButtonClickListener(
selection -> {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(selection);
SimpleDateFormat format =
new SimpleDateFormat(
"yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
String formattedDate = format.format(calendar.getTime());
viewBinding.prDueDate.setText(formattedDate);
});
}
@Override @Override
public void labelsInterface(List<String> data) { public void labelsInterface(List<String> data) {
@ -325,7 +510,6 @@ public class CreatePullRequestActivity extends BaseActivity
viewBinding.mergeIntoBranchSpinner.setAdapter(adapter); viewBinding.mergeIntoBranchSpinner.setAdapter(adapter);
viewBinding.pullFromBranchSpinner.setAdapter(adapter); viewBinding.pullFromBranchSpinner.setAdapter(adapter);
enableProcessButton();
} }
} }
} }
@ -333,7 +517,10 @@ public class CreatePullRequestActivity extends BaseActivity
@Override @Override
public void onFailure(@NonNull Call<List<Branch>> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<List<Branch>> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
@ -382,7 +569,6 @@ public class CreatePullRequestActivity extends BaseActivity
new ArrayList<>(milestonesList.keySet())); new ArrayList<>(milestonesList.keySet()));
viewBinding.milestonesSpinner.setAdapter(adapter); viewBinding.milestonesSpinner.setAdapter(adapter);
enableProcessButton();
viewBinding.milestonesSpinner.setOnItemClickListener( viewBinding.milestonesSpinner.setOnItemClickListener(
(parent, view, position, id) -> { (parent, view, position, id) -> {
@ -407,51 +593,14 @@ public class CreatePullRequestActivity extends BaseActivity
public void onFailure( public void onFailure(
@NonNull Call<List<Milestone>> call, @NonNull Throwable t) { @NonNull Call<List<Milestone>> call, @NonNull Throwable t) {
Toasty.error(ctx, getString(R.string.genericServerResponseError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }
private void setDueDate() {
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
final int mMonth = c.get(Calendar.MONTH);
final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog =
new DatePickerDialog(
this,
(view, year, monthOfYear, dayOfMonth) -> {
viewBinding.prDueDate.setText(
getString(
R.string.setDueDate,
year,
(monthOfYear + 1),
dayOfMonth));
currentDate = new Date(year - 1900, monthOfYear, dayOfMonth);
},
mYear,
mMonth,
mDay);
datePickerDialog.show();
}
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
viewBinding.createPr.setEnabled(false);
}
private void enableProcessButton() {
viewBinding.createPr.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,15 +1,10 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
@ -25,9 +20,8 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateReleaseBinding; import org.mian.gitnex.databinding.ActivityCreateReleaseBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.RepositoryContext; import org.mian.gitnex.helpers.contexts.RepositoryContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -39,10 +33,8 @@ public class CreateReleaseActivity extends BaseActivity {
private ActivityCreateReleaseBinding binding; private ActivityCreateReleaseBinding binding;
List<String> branchesList = new ArrayList<>(); List<String> branchesList = new ArrayList<>();
private View.OnClickListener onClickListener;
private String selectedBranch; private String selectedBranch;
private RepositoryContext repository; private RepositoryContext repository;
private final View.OnClickListener createReleaseListener = v -> processNewRelease();
private boolean renderMd = false; private boolean renderMd = false;
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
@ -53,19 +45,9 @@ public class CreateReleaseActivity extends BaseActivity {
binding = ActivityCreateReleaseBinding.inflate(getLayoutInflater()); binding = ActivityCreateReleaseBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
repository = RepositoryContext.fromIntent(getIntent()); repository = RepositoryContext.fromIntent(getIntent());
binding.releaseTitle.requestFocus();
assert imm != null;
imm.showSoftInput(binding.releaseTitle, InputMethodManager.SHOW_IMPLICIT);
binding.releaseContent.setOnTouchListener( binding.releaseContent.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
touchView.getParent().requestDisallowInterceptTouchEvent(true); touchView.getParent().requestDisallowInterceptTouchEvent(true);
@ -78,90 +60,72 @@ public class CreateReleaseActivity extends BaseActivity {
return false; return false;
}); });
initCloseListener(); binding.topAppBar.setNavigationOnClickListener(
binding.close.setOnClickListener(onClickListener); v -> {
finish();
});
binding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
Objects.requireNonNull(
binding.releaseContent
.getText())
.toString())),
binding.markdownPreview);
binding.markdownPreview.setVisibility(View.VISIBLE);
binding.releaseContentLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.releaseContentLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else if (id == R.id.create) {
processNewRelease();
return true;
} else if (id == R.id.create_tag) {
createNewTag();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
getBranches(repository.getOwner(), repository.getName()); getBranches(repository.getOwner(), repository.getName());
disableProcessButton();
if (!connToInternet) {
disableProcessButton();
} else {
binding.createNewRelease.setOnClickListener(createReleaseListener);
}
binding.createNewTag.setOnClickListener(v -> createNewTag());
}
@Override
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.markdown_switcher, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
Objects.requireNonNull(binding.releaseContent.getText())
.toString())),
binding.markdownPreview);
binding.markdownPreview.setVisibility(View.VISIBLE);
binding.releaseContentLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.releaseContentLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
} }
private void createNewTag() { private void createNewTag() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String tagName = Objects.requireNonNull(binding.releaseTagName.getText()).toString(); String tagName = Objects.requireNonNull(binding.releaseTagName.getText()).toString();
String message = String message =
Objects.requireNonNull(binding.releaseTitle.getText()).toString() Objects.requireNonNull(binding.releaseTitle.getText())
+ "\n\n" + "\n\n"
+ Objects.requireNonNull(binding.releaseContent.getText()).toString(); + Objects.requireNonNull(binding.releaseContent.getText());
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (tagName.equals("")) { if (tagName.equals("")) {
Toasty.error(ctx, getString(R.string.tagNameErrorEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.tagNameErrorEmpty));
return; return;
} }
if (selectedBranch == null) { if (selectedBranch == null) {
Toasty.error(ctx, getString(R.string.selectBranchError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.selectBranchError));
return; return;
} }
disableProcessButton();
CreateTagOption createReleaseJson = new CreateTagOption(); CreateTagOption createReleaseJson = new CreateTagOption();
createReleaseJson.setMessage(message); createReleaseJson.setMessage(message);
createReleaseJson.setTagName(tagName); createReleaseJson.setTagName(tagName);
@ -173,7 +137,7 @@ public class CreateReleaseActivity extends BaseActivity {
repository.getOwner(), repository.getName(), createReleaseJson); repository.getOwner(), repository.getName(), createReleaseJson);
call.enqueue( call.enqueue(
new Callback<Tag>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -182,35 +146,38 @@ public class CreateReleaseActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
RepoDetailActivity.updateFABActions = true; RepoDetailActivity.updateFABActions = true;
Toasty.success(ctx, getString(R.string.tagCreated)); SnackBar.success(
finish(); ctx,
findViewById(android.R.id.content),
getString(R.string.tagCreated));
new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 403) { } else if (response.code() == 403) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); ctx,
findViewById(android.R.id.content),
getString(R.string.authorizeError));
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Tag> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Tag> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void processNewRelease() { private void processNewRelease() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String newReleaseTagName = String newReleaseTagName =
Objects.requireNonNull(binding.releaseTagName.getText()).toString(); Objects.requireNonNull(binding.releaseTagName.getText()).toString();
String newReleaseTitle = Objects.requireNonNull(binding.releaseTitle.getText()).toString(); String newReleaseTitle = Objects.requireNonNull(binding.releaseTitle.getText()).toString();
@ -220,31 +187,24 @@ public class CreateReleaseActivity extends BaseActivity {
boolean newReleaseType = binding.releaseType.isChecked(); boolean newReleaseType = binding.releaseType.isChecked();
boolean newReleaseDraft = binding.releaseDraft.isChecked(); boolean newReleaseDraft = binding.releaseDraft.isChecked();
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (newReleaseTitle.equals("")) { if (newReleaseTitle.equals("")) {
SnackBar.error(
Toasty.error(ctx, getString(R.string.titleErrorEmpty)); ctx, findViewById(android.R.id.content), getString(R.string.titleErrorEmpty));
return; return;
} }
if (newReleaseTagName.equals("")) { if (newReleaseTagName.equals("")) {
SnackBar.error(
Toasty.error(ctx, getString(R.string.tagNameErrorEmpty)); ctx, findViewById(android.R.id.content), getString(R.string.tagNameErrorEmpty));
return; return;
} }
if (checkBranch == null) { if (checkBranch == null) {
SnackBar.error(
Toasty.error(ctx, getString(R.string.selectBranchError)); ctx, findViewById(android.R.id.content), getString(R.string.selectBranchError));
return; return;
} }
disableProcessButton();
createNewReleaseFunc( createNewReleaseFunc(
repository.getOwner(), repository.getOwner(),
repository.getName(), repository.getName(),
@ -289,31 +249,37 @@ public class CreateReleaseActivity extends BaseActivity {
if (response.code() == 201) { if (response.code() == 201) {
RepoDetailActivity.updateFABActions = true; RepoDetailActivity.updateFABActions = true;
Toasty.success(ctx, getString(R.string.releaseCreatedText)); SnackBar.success(
finish(); ctx,
findViewById(android.R.id.content),
getString(R.string.releaseCreatedText));
new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 403) { } else if (response.code() == 403) {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.authorizeError)); ctx,
findViewById(android.R.id.content),
getString(R.string.authorizeError));
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)); ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, ctx.getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Release> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Release> call, @NonNull Throwable t) {}
enableProcessButton();
}
}); });
} }
@ -349,7 +315,6 @@ public class CreateReleaseActivity extends BaseActivity {
branchesList); branchesList);
binding.releaseBranch.setAdapter(adapter); binding.releaseBranch.setAdapter(adapter);
enableProcessButton();
binding.releaseBranch.setOnItemClickListener( binding.releaseBranch.setOnItemClickListener(
(parent, view, position, id) -> (parent, view, position, id) ->
@ -366,21 +331,6 @@ public class CreateReleaseActivity extends BaseActivity {
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
binding.createNewTag.setEnabled(false);
binding.createNewRelease.setEnabled(false);
}
private void enableProcessButton() {
binding.createNewTag.setEnabled(true);
binding.createNewRelease.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -1,22 +1,16 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.gitnex.tea4j.v2.models.CreateRepoOption; import org.gitnex.tea4j.v2.models.CreateRepoOption;
import org.gitnex.tea4j.v2.models.Organization; import org.gitnex.tea4j.v2.models.Organization;
@ -26,7 +20,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityCreateRepoBinding; import org.mian.gitnex.databinding.ActivityCreateRepoBinding;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -38,103 +32,121 @@ public class CreateRepoActivity extends BaseActivity {
// https://github.com/go-gitea/gitea/blob/52cfd2743c0e85b36081cf80a850e6a5901f1865/models/repo.go#L964-L967 // https://github.com/go-gitea/gitea/blob/52cfd2743c0e85b36081cf80a850e6a5901f1865/models/repo.go#L964-L967
final List<String> reservedRepoNames = Arrays.asList(".", ".."); final List<String> reservedRepoNames = Arrays.asList(".", "..");
final Pattern reservedRepoPatterns = Pattern.compile("\\.(git|wiki)$"); final Pattern reservedRepoPatterns = Pattern.compile("\\.(git|wiki)$");
public ImageView closeActivity;
List<String> organizationsList = new ArrayList<>(); List<String> organizationsList = new ArrayList<>();
private View.OnClickListener onClickListener; List<String> issueLabelsList = new ArrayList<>();
private AutoCompleteTextView spinner; List<String> licenseList = new ArrayList<>();
private Button createRepo; private ActivityCreateRepoBinding activityCreateRepoBinding;
private EditText repoName;
private EditText repoDesc;
private CheckBox repoAccess;
private String loginUid; private String loginUid;
private String selectedOwner; private String selectedOwner;
private final View.OnClickListener createRepoListener = v -> processNewRepo(); private String selectedIssueLabels;
private String selectedLicense;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ActivityCreateRepoBinding activityCreateRepoBinding = activityCreateRepoBinding = ActivityCreateRepoBinding.inflate(getLayoutInflater());
ActivityCreateRepoBinding.inflate(getLayoutInflater());
setContentView(activityCreateRepoBinding.getRoot()); setContentView(activityCreateRepoBinding.getRoot());
boolean connToInternet = AppUtil.hasNetworkConnection(ctx);
loginUid = getAccount().getAccount().getUserName(); loginUid = getAccount().getAccount().getUserName();
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
closeActivity = activityCreateRepoBinding.close;
repoName = activityCreateRepoBinding.newRepoName;
repoDesc = activityCreateRepoBinding.newRepoDescription;
repoAccess = activityCreateRepoBinding.newRepoPrivate;
repoName.requestFocus();
assert imm != null;
imm.showSoftInput(repoName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
spinner = activityCreateRepoBinding.ownerSpinner;
getOrganizations(loginUid); getOrganizations(loginUid);
createRepo = activityCreateRepoBinding.createNewRepoButton; activityCreateRepoBinding.topAppBar.setNavigationOnClickListener(v -> finish());
disableProcessButton();
if (!connToInternet) { MenuItem attachment = activityCreateRepoBinding.topAppBar.getMenu().getItem(0);
attachment.setVisible(false);
MenuItem markdown = activityCreateRepoBinding.topAppBar.getMenu().getItem(1);
markdown.setVisible(false);
disableProcessButton(); String[] licenses = getResources().getStringArray(R.array.licenses);
} else { Collections.addAll(licenseList, licenses);
getLicenses();
createRepo.setOnClickListener(createRepoListener); issueLabelsList.add(getString(R.string.advanced));
} issueLabelsList.add(getString(R.string.defaultText));
getIssueLabels();
activityCreateRepoBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.create) {
processNewRepo();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
} }
private void processNewRepo() { private void processNewRepo() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); String newRepoName =
Objects.requireNonNull(activityCreateRepoBinding.newRepoName.getText()).toString();
String newRepoName = repoName.getText().toString(); String newRepoDesc =
String newRepoDesc = repoDesc.getText().toString(); Objects.requireNonNull(activityCreateRepoBinding.newRepoDescription.getText())
boolean newRepoAccess = repoAccess.isChecked(); .toString();
boolean newRepoAccess = activityCreateRepoBinding.newRepoPrivate.isChecked();
if (!connToInternet) { boolean repoAsTemplate = activityCreateRepoBinding.setAsTemplate.isChecked();
String defaultBranch =
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); Objects.requireNonNull(activityCreateRepoBinding.defaultBranch.getText())
return; .toString();
}
if (!newRepoDesc.equals("")) { if (!newRepoDesc.equals("")) {
if (newRepoDesc.length() > 255) { if (newRepoDesc.length() > 255) {
Toasty.warning(ctx, getString(R.string.repoDescError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.repoDescError));
return; return;
} }
} }
if (newRepoName.equals("")) { if (newRepoName.equals("")) {
Toasty.error(ctx, getString(R.string.repoNameErrorEmpty)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.repoNameErrorEmpty));
} else if (!AppUtil.checkStrings(newRepoName)) { } else if (!AppUtil.checkStrings(newRepoName)) {
Toasty.warning(ctx, getString(R.string.repoNameErrorInvalid)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.repoNameErrorInvalid));
} else if (reservedRepoNames.contains(newRepoName)) { } else if (reservedRepoNames.contains(newRepoName)) {
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedName)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.repoNameErrorReservedName));
} else if (reservedRepoPatterns.matcher(newRepoName).find()) { } else if (reservedRepoPatterns.matcher(newRepoName).find()) {
Toasty.warning(ctx, getString(R.string.repoNameErrorReservedPatterns)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.repoNameErrorReservedPatterns));
} else if (defaultBranch.equalsIgnoreCase("")) {
SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.repoDefaultBranchError));
} else if (selectedOwner == null) { } else if (selectedOwner == null) {
Toasty.error(ctx, getString(R.string.repoOwnerError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.repoOwnerError));
} else { } else {
disableProcessButton(); createNewRepository(
createNewRepository(loginUid, newRepoName, newRepoDesc, selectedOwner, newRepoAccess); loginUid,
newRepoName,
newRepoDesc,
selectedOwner,
newRepoAccess,
defaultBranch,
repoAsTemplate);
} }
} }
@ -143,7 +155,9 @@ public class CreateRepoActivity extends BaseActivity {
String repoName, String repoName,
String repoDesc, String repoDesc,
String selectedOwner, String selectedOwner,
boolean isPrivate) { boolean isPrivate,
String defaultBranch,
boolean repoAsTemplate) {
CreateRepoOption createRepository = new CreateRepoOption(); CreateRepoOption createRepository = new CreateRepoOption();
createRepository.setAutoInit(true); createRepository.setAutoInit(true);
@ -151,6 +165,10 @@ public class CreateRepoActivity extends BaseActivity {
createRepository.setPrivate(isPrivate); createRepository.setPrivate(isPrivate);
createRepository.setReadme("Default"); createRepository.setReadme("Default");
createRepository.setName(repoName); createRepository.setName(repoName);
createRepository.setDefaultBranch(defaultBranch);
createRepository.setIssueLabels(selectedIssueLabels);
createRepository.setTemplate(repoAsTemplate);
createRepository.setLicense(selectedLicense);
Call<Repository> call; Call<Repository> call;
if (selectedOwner.equals(loginUid)) { if (selectedOwner.equals(loginUid)) {
@ -164,7 +182,7 @@ public class CreateRepoActivity extends BaseActivity {
} }
call.enqueue( call.enqueue(
new Callback<Repository>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -175,40 +193,68 @@ public class CreateRepoActivity extends BaseActivity {
MainActivity.reloadRepos = true; MainActivity.reloadRepos = true;
OrganizationDetailActivity.updateOrgFABActions = true; OrganizationDetailActivity.updateOrgFABActions = true;
Toasty.success(ctx, getString(R.string.repoCreated));
enableProcessButton(); SnackBar.success(
finish(); ctx,
findViewById(android.R.id.content),
getString(R.string.repoCreated));
new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 409) { } else if (response.code() == 409) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.repoExistsError)); ctx,
findViewById(android.R.id.content),
getString(R.string.repoExistsError));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Repository> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Repository> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void getIssueLabels() {
ArrayAdapter<String> adapter =
new ArrayAdapter<>(
CreateRepoActivity.this, R.layout.list_spinner_items, issueLabelsList);
activityCreateRepoBinding.issueLabels.setAdapter(adapter);
activityCreateRepoBinding.issueLabels.setOnItemClickListener(
(parent, view, position, id) ->
selectedIssueLabels = issueLabelsList.get(position));
}
private void getLicenses() {
ArrayAdapter<String> adapter =
new ArrayAdapter<>(
CreateRepoActivity.this, R.layout.list_spinner_items, licenseList);
activityCreateRepoBinding.licenses.setAdapter(adapter);
activityCreateRepoBinding.licenses.setOnItemClickListener(
(parent, view, position, id) -> selectedLicense = licenseList.get(position));
}
private void getOrganizations(final String userLogin) { private void getOrganizations(final String userLogin) {
Call<List<Organization>> call = Call<List<Organization>> call =
RetrofitClient.getApiInterface(ctx).orgListCurrentUserOrgs(1, 50); RetrofitClient.getApiInterface(ctx).orgListCurrentUserOrgs(1, 50);
call.enqueue( call.enqueue(
new Callback<List<Organization>>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -247,9 +293,9 @@ public class CreateRepoActivity extends BaseActivity {
R.layout.list_spinner_items, R.layout.list_spinner_items,
organizationsList); organizationsList);
spinner.setAdapter(adapter); activityCreateRepoBinding.ownerSpinner.setAdapter(adapter);
spinner.setOnItemClickListener( activityCreateRepoBinding.ownerSpinner.setOnItemClickListener(
(parent, view, position, id) -> (parent, view, position, id) ->
selectedOwner = organizationsList.get(position)); selectedOwner = organizationsList.get(position));
@ -260,7 +306,7 @@ public class CreateRepoActivity extends BaseActivity {
new Handler(Looper.getMainLooper()) new Handler(Looper.getMainLooper())
.postDelayed( .postDelayed(
() -> { () -> {
spinner.setText( activityCreateRepoBinding.ownerSpinner.setText(
organizationsList.get(selectOwnerById), organizationsList.get(selectOwnerById),
false); false);
selectedOwner = selectedOwner =
@ -270,36 +316,15 @@ public class CreateRepoActivity extends BaseActivity {
getIntent().removeExtra("organizationAction"); getIntent().removeExtra("organizationAction");
} }
enableProcessButton();
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} }
} }
@Override @Override
public void onFailure( public void onFailure(
@NonNull Call<List<Organization>> call, @NonNull Throwable t) { @NonNull Call<List<Organization>> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void disableProcessButton() {
createRepo.setEnabled(false);
}
private void enableProcessButton() {
createRepo.setEnabled(true);
}
} }

View File

@ -1,20 +1,15 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.os.Handler;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import org.gitnex.tea4j.v2.models.CreateTeamOption; import org.gitnex.tea4j.v2.models.CreateTeamOption;
import org.gitnex.tea4j.v2.models.Team; import org.gitnex.tea4j.v2.models.Team;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -23,26 +18,17 @@ import org.mian.gitnex.databinding.ActivityCreateTeamByOrgBinding;
import org.mian.gitnex.fragments.OrganizationTeamsFragment; import org.mian.gitnex.fragments.OrganizationTeamsFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
/** /**
* @author M M Arif * @author M M Arif
*/ */
public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClickListener { public class CreateTeamByOrgActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private TextView teamName;
private TextView teamDesc;
private TextView teamPermission;
private TextView teamPermissionDetail;
private TextView teamAccessControls;
private TextView teamAccessControlsArray;
private Button createTeamButton;
private final String[] permissionList = {"Read", "Write", "Admin"}; private final String[] permissionList = {"Read", "Write", "Admin"};
public int permissionSelectedChoice = -1; public int permissionSelectedChoice = -1;
private final String[] accessControlsList = private final String[] accessControlsList =
new String[] { new String[] {
"Code", "Code",
@ -53,8 +39,8 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
"External Wiki", "External Wiki",
"External Issues" "External Issues"
}; };
private List<String> pushAccessList; private List<String> pushAccessList;
private ActivityCreateTeamByOrgBinding activityCreateTeamByOrgBinding;
private final boolean[] selectedAccessControlsTrueFalse = private final boolean[] selectedAccessControlsTrueFalse =
new boolean[] {false, false, false, false, false, false, false}; new boolean[] {false, false, false, false, false, false, false};
@ -64,32 +50,18 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ActivityCreateTeamByOrgBinding activityCreateTeamByOrgBinding = activityCreateTeamByOrgBinding =
ActivityCreateTeamByOrgBinding.inflate(getLayoutInflater()); ActivityCreateTeamByOrgBinding.inflate(getLayoutInflater());
setContentView(activityCreateTeamByOrgBinding.getRoot()); setContentView(activityCreateTeamByOrgBinding.getRoot());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); MenuItem attachment = activityCreateTeamByOrgBinding.topAppBar.getMenu().getItem(0);
MenuItem markdown = activityCreateTeamByOrgBinding.topAppBar.getMenu().getItem(1);
attachment.setVisible(false);
markdown.setVisible(false);
InputMethodManager imm = activityCreateTeamByOrgBinding.topAppBar.setNavigationOnClickListener(v -> finish());
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
ImageView closeActivity = activityCreateTeamByOrgBinding.close; activityCreateTeamByOrgBinding.teamPermission.setOnClickListener(
teamName = activityCreateTeamByOrgBinding.teamName;
teamDesc = activityCreateTeamByOrgBinding.teamDesc;
teamPermission = activityCreateTeamByOrgBinding.teamPermission;
teamPermissionDetail = activityCreateTeamByOrgBinding.teamPermissionDetail;
teamAccessControls = activityCreateTeamByOrgBinding.teamAccessControls;
teamAccessControlsArray = activityCreateTeamByOrgBinding.teamAccessControlsArray;
createTeamButton = activityCreateTeamByOrgBinding.createTeamButton;
teamName.requestFocus();
assert imm != null;
imm.showSoftInput(teamName, InputMethodManager.SHOW_IMPLICIT);
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
teamPermission.setOnClickListener(
view -> { view -> {
MaterialAlertDialogBuilder materialAlertDialogBuilderPerm = MaterialAlertDialogBuilder materialAlertDialogBuilderPerm =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
@ -100,29 +72,37 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
permissionSelectedChoice, permissionSelectedChoice,
(dialogInterface, i) -> { (dialogInterface, i) -> {
permissionSelectedChoice = i; permissionSelectedChoice = i;
teamPermission.setText(permissionList[i]); activityCreateTeamByOrgBinding.teamPermission
.setText(permissionList[i]);
switch (permissionList[i]) { switch (permissionList[i]) {
case "Read": case "Read":
teamPermissionDetail.setVisibility( activityCreateTeamByOrgBinding
.teamPermissionDetail.setVisibility(
View.VISIBLE); View.VISIBLE);
teamPermissionDetail.setText( activityCreateTeamByOrgBinding
.teamPermissionDetail.setText(
R.string.newTeamPermissionRead); R.string.newTeamPermissionRead);
break; break;
case "Write": case "Write":
teamPermissionDetail.setVisibility( activityCreateTeamByOrgBinding
.teamPermissionDetail.setVisibility(
View.VISIBLE); View.VISIBLE);
teamPermissionDetail.setText( activityCreateTeamByOrgBinding
.teamPermissionDetail.setText(
R.string.newTeamPermissionWrite); R.string.newTeamPermissionWrite);
break; break;
case "Admin": case "Admin":
teamPermissionDetail.setVisibility( activityCreateTeamByOrgBinding
.teamPermissionDetail.setVisibility(
View.VISIBLE); View.VISIBLE);
teamPermissionDetail.setText( activityCreateTeamByOrgBinding
.teamPermissionDetail.setText(
R.string.newTeamPermissionAdmin); R.string.newTeamPermissionAdmin);
break; break;
default: default:
teamPermissionDetail.setVisibility( activityCreateTeamByOrgBinding
.teamPermissionDetail.setVisibility(
View.GONE); View.GONE);
break; break;
} }
@ -133,10 +113,10 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
materialAlertDialogBuilderPerm.create().show(); materialAlertDialogBuilderPerm.create().show();
}); });
teamAccessControls.setOnClickListener( activityCreateTeamByOrgBinding.teamAccessControls.setOnClickListener(
v -> { v -> {
teamAccessControls.setText(""); activityCreateTeamByOrgBinding.teamAccessControls.setText("");
teamAccessControlsArray.setText(""); activityCreateTeamByOrgBinding.teamAccessControlsArray.setText("");
pushAccessList = Arrays.asList(accessControlsList); pushAccessList = Arrays.asList(accessControlsList);
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
@ -181,19 +161,23 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if (value) { if (value) {
teamAccessControls.setText( activityCreateTeamByOrgBinding
.teamAccessControls.setText(
getString( getString(
R.string R.string
.newTeamPermissionValues, .newTeamPermissionValues,
teamAccessControls activityCreateTeamByOrgBinding
.teamAccessControls
.getText(), .getText(),
pushAccessList.get( pushAccessList.get(
selectedVal))); selectedVal)));
teamAccessControlsArray.setText( activityCreateTeamByOrgBinding
.teamAccessControlsArray.setText(
getString( getString(
R.string R.string
.newTeamPermissionValuesFinal, .newTeamPermissionValuesFinal,
teamAccessControlsArray activityCreateTeamByOrgBinding
.teamAccessControlsArray
.getText(), .getText(),
repoCode)); repoCode));
} }
@ -203,20 +187,26 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
String data = String data =
String.valueOf( String.valueOf(
teamAccessControls.getText()); activityCreateTeamByOrgBinding
.teamAccessControls
.getText());
if (!data.equals("")) { if (!data.equals("")) {
teamAccessControls.setText( activityCreateTeamByOrgBinding
.teamAccessControls.setText(
data.substring(0, data.length() - 2)); data.substring(0, data.length() - 2));
} }
String dataArray = String dataArray =
String.valueOf( String.valueOf(
teamAccessControlsArray.getText()); activityCreateTeamByOrgBinding
.teamAccessControlsArray
.getText());
if (!dataArray.equals("")) { if (!dataArray.equals("")) {
teamAccessControlsArray.setText( activityCreateTeamByOrgBinding
.teamAccessControlsArray.setText(
dataArray.substring( dataArray.substring(
0, dataArray.length() - 2)); 0, dataArray.length() - 2));
} }
@ -225,47 +215,47 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
createTeamButton.setEnabled(false); activityCreateTeamByOrgBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (!connToInternet) { if (id == R.id.create) {
processCreateTeam();
createTeamButton.setEnabled(false); return true;
GradientDrawable shape = new GradientDrawable(); } else {
shape.setCornerRadius(8); return super.onOptionsItemSelected(menuItem);
shape.setColor(ResourcesCompat.getColor(getResources(), R.color.hintColor, null)); }
createTeamButton.setBackground(shape); });
} else {
createTeamButton.setEnabled(true);
createTeamButton.setOnClickListener(this);
}
} }
private void processCreateTeam() { private void processCreateTeam() {
final String orgName = getIntent().getStringExtra("orgName"); final String orgName = getIntent().getStringExtra("orgName");
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx); String newTeamName =
String newTeamName = teamName.getText().toString(); Objects.requireNonNull(activityCreateTeamByOrgBinding.teamName.getText())
String newTeamDesc = teamDesc.getText().toString(); .toString();
String newTeamPermission = teamPermission.getText().toString().toLowerCase(); String newTeamDesc =
String newTeamAccessControls = teamAccessControlsArray.getText().toString(); Objects.requireNonNull(activityCreateTeamByOrgBinding.teamDesc.getText())
.toString();
if (!connToInternet) { String newTeamPermission =
Objects.requireNonNull(activityCreateTeamByOrgBinding.teamPermission.getText())
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection)); .toString()
return; .toLowerCase();
} String newTeamAccessControls =
activityCreateTeamByOrgBinding.teamAccessControlsArray.getText().toString();
if (newTeamName.equals("")) { if (newTeamName.equals("")) {
Toasty.error(ctx, getString(R.string.teamNameEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.teamNameEmpty));
return; return;
} }
if (!AppUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) { if (!AppUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
Toasty.warning(ctx, getString(R.string.teamNameError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.teamNameError));
return; return;
} }
@ -273,20 +263,25 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
if (!AppUtil.checkStrings(newTeamDesc)) { if (!AppUtil.checkStrings(newTeamDesc)) {
Toasty.warning(ctx, getString(R.string.teamDescError)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.teamDescError));
return; return;
} }
if (newTeamDesc.length() > 100) { if (newTeamDesc.length() > 100) {
Toasty.warning(ctx, getString(R.string.teamDescLimit)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.teamDescLimit));
return; return;
} }
} }
if (newTeamPermission.equals("")) { if (newTeamPermission.equals("")) {
Toasty.error(ctx, getString(R.string.teamPermissionEmpty)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.teamPermissionEmpty));
return; return;
} }
@ -329,7 +324,7 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
RetrofitClient.getApiInterface(ctx).orgCreateTeam(orgName, createNewTeamJson); RetrofitClient.getApiInterface(ctx).orgCreateTeam(orgName, createNewTeamJson);
call3.enqueue( call3.enqueue(
new Callback<Team>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -341,39 +336,32 @@ public class CreateTeamByOrgActivity extends BaseActivity implements View.OnClic
OrganizationTeamsFragment.resumeTeams = true; OrganizationTeamsFragment.resumeTeams = true;
Toasty.success(ctx, getString(R.string.teamCreated)); SnackBar.success(
finish(); ctx,
findViewById(android.R.id.content),
getString(R.string.teamCreated));
new Handler().postDelayed(() -> finish(), 3000);
} }
} else if (response2.code() == 404) { } else if (response2.code() == 404) {
Toasty.warning(ctx, getString(R.string.apiNotFound)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.apiNotFound));
} else if (response2.code() == 401) { } else if (response2.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
Toasty.error(ctx, getString(R.string.genericError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Team> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Team> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
}
}); });
} }
@Override
public void onClick(View v) {
if (v == createTeamButton) {
processCreateTeam();
}
}
private void initCloseListener() {
onClickListener = view -> finish();
}
} }

View File

@ -1,22 +1,18 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.google.android.material.datepicker.MaterialDatePicker;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -25,7 +21,9 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone;
import org.gitnex.tea4j.v2.models.EditIssueOption; import org.gitnex.tea4j.v2.models.EditIssueOption;
import org.gitnex.tea4j.v2.models.Issue; import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.Milestone; import org.gitnex.tea4j.v2.models.Milestone;
@ -35,10 +33,9 @@ import org.mian.gitnex.databinding.ActivityEditIssueBinding;
import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.helpers.contexts.IssueContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -46,15 +43,12 @@ import retrofit2.Callback;
/** /**
* @author M M Arif * @author M M Arif
*/ */
public class EditIssueActivity extends BaseActivity implements View.OnClickListener { public class EditIssueActivity extends BaseActivity {
private ActivityEditIssueBinding binding; private ActivityEditIssueBinding binding;
private final String msState = "open"; private final String msState = "open";
private final LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>(); private final LinkedHashMap<String, Milestone> milestonesList = new LinkedHashMap<>();
private View.OnClickListener onClickListener;
private int resultLimit;
private int milestoneId = 0; private int milestoneId = 0;
private Date currentDate = null;
private IssueContext issue; private IssueContext issue;
private boolean renderMd = false; private boolean renderMd = false;
@ -66,17 +60,16 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
binding = ActivityEditIssueBinding.inflate(getLayoutInflater()); binding = ActivityEditIssueBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
InputMethodManager imm = int resultLimit = Constants.getCurrentResultLimit(ctx);
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
resultLimit = Constants.getCurrentResultLimit(ctx);
issue = IssueContext.fromIntent(getIntent()); issue = IssueContext.fromIntent(getIntent());
binding.editIssueTitle.requestFocus(); binding.topAppBar.setNavigationOnClickListener(v -> finish());
assert imm != null;
imm.showSoftInput(binding.editIssueTitle, InputMethodManager.SHOW_IMPLICIT); MenuItem attachment = binding.topAppBar.getMenu().getItem(0);
MenuItem create = binding.topAppBar.getMenu().getItem(2);
attachment.setVisible(false);
create.setTitle(getString(R.string.menuEditText));
binding.editIssueDescription.setOnTouchListener( binding.editIssueDescription.setOnTouchListener(
(touchView, motionEvent) -> { (touchView, motionEvent) -> {
@ -90,23 +83,51 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
return false; return false;
}); });
initCloseListener();
binding.close.setOnClickListener(onClickListener);
binding.editIssueDueDate.setOnClickListener(this);
binding.editIssueButton.setOnClickListener(this);
if (issue.getIssueType().equalsIgnoreCase("Pull")) { if (issue.getIssueType().equalsIgnoreCase("Pull")) {
binding.topAppBar.setTitle(
binding.toolbarTitle.setText(
getString(R.string.editPrNavHeader, String.valueOf(issue.getIssueIndex()))); getString(R.string.editPrNavHeader, String.valueOf(issue.getIssueIndex())));
} else { } else {
binding.topAppBar.setTitle(
binding.toolbarTitle.setText(
getString(R.string.editIssueNavHeader, String.valueOf(issue.getIssueIndex()))); getString(R.string.editIssueNavHeader, String.valueOf(issue.getIssueIndex())));
} }
disableProcessButton(); showDatePickerDialog();
binding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(
binding.editIssueDescription.getText())
.toString()),
binding.markdownPreview,
issue.getRepository());
binding.markdownPreview.setVisibility(View.VISIBLE);
binding.editIssueDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.editIssueDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else if (id == R.id.create) {
processEditIssue();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
getIssue( getIssue(
issue.getRepository().getOwner(), issue.getRepository().getOwner(),
issue.getRepository().getName(), issue.getRepository().getName(),
@ -119,81 +140,29 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
@Override
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.markdown_switcher, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.markdown) {
if (!renderMd) {
Markdown.render(
ctx,
EmojiParser.parseToUnicode(
Objects.requireNonNull(binding.editIssueDescription.getText())
.toString()),
binding.markdownPreview,
issue.getRepository());
binding.markdownPreview.setVisibility(View.VISIBLE);
binding.editIssueDescriptionLayout.setVisibility(View.GONE);
renderMd = true;
} else {
binding.markdownPreview.setVisibility(View.GONE);
binding.editIssueDescriptionLayout.setVisibility(View.VISIBLE);
renderMd = false;
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void processEditIssue() { private void processEditIssue() {
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
String editIssueTitleForm = String editIssueTitleForm =
Objects.requireNonNull(binding.editIssueTitle.getText()).toString(); Objects.requireNonNull(binding.editIssueTitle.getText()).toString();
String editIssueDescriptionForm = String editIssueDescriptionForm =
Objects.requireNonNull(binding.editIssueDescription.getText()).toString(); Objects.requireNonNull(binding.editIssueDescription.getText()).toString();
String dueDate = Objects.requireNonNull(binding.editIssueDueDate.getText()).toString();
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (editIssueTitleForm.equals("")) { if (editIssueTitleForm.equals("")) {
Toasty.error(ctx, getString(R.string.issueTitleEmpty)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.issueTitleEmpty));
return; return;
} }
disableProcessButton();
editIssue( editIssue(
issue.getRepository().getOwner(), issue.getRepository().getOwner(),
issue.getRepository().getName(), issue.getRepository().getName(),
issue.getIssueIndex(), issue.getIssueIndex(),
editIssueTitleForm, editIssueTitleForm,
editIssueDescriptionForm, editIssueDescriptionForm,
milestoneId); milestoneId,
dueDate);
} }
private void editIssue( private void editIssue(
@ -202,12 +171,21 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
int issueIndex, int issueIndex,
String title, String title,
String description, String description,
int milestoneId) { int milestoneId,
String dueDate) {
EditIssueOption issueData = new EditIssueOption(); EditIssueOption issueData = new EditIssueOption();
issueData.setTitle(title); issueData.setTitle(title);
issueData.setBody(description); issueData.setBody(description);
issueData.setDueDate(currentDate); String[] date = dueDate.split("-");
if (!dueDate.equalsIgnoreCase("")) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, Integer.parseInt(date[1]));
calendar.set(Calendar.DATE, Integer.parseInt(date[2]));
Date dueDate_ = calendar.getTime();
issueData.setDueDate(dueDate_);
}
issueData.setMilestone((long) milestoneId); issueData.setMilestone((long) milestoneId);
Call<Issue> call = Call<Issue> call =
@ -215,7 +193,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
.issueEditIssue(repoOwner, repoName, (long) issueIndex, issueData); .issueEditIssue(repoOwner, repoName, (long) issueIndex, issueData);
call.enqueue( call.enqueue(
new Callback<Issue>() { new Callback<>() {
@Override @Override
public void onResponse( public void onResponse(
@ -226,10 +204,16 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
if (issue.getIssueType().equalsIgnoreCase("Pull")) { if (issue.getIssueType().equalsIgnoreCase("Pull")) {
Toasty.success(ctx, getString(R.string.editPrSuccessMessage)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.editPrSuccessMessage));
} else { } else {
Toasty.success(ctx, getString(R.string.editIssueSuccessMessage)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.editIssueSuccessMessage));
} }
Intent result = new Intent(); Intent result = new Intent();
@ -238,57 +222,44 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
PullRequestsFragment.resumePullRequests = PullRequestsFragment.resumePullRequests =
issue.getIssue().getPullRequest() != null; issue.getIssue().getPullRequest() != null;
setResult(200, result); setResult(200, result);
finish(); new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) {}
Log.e("onFailure", t.toString());
enableProcessButton();
}
}); });
} }
@Override private void showDatePickerDialog() {
public void onClick(View v) {
if (v == binding.editIssueDueDate) { MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
builder.setSelection(Calendar.getInstance().getTimeInMillis());
builder.setTitleText(R.string.newIssueDueDateTitle);
MaterialDatePicker<Long> materialDatePicker = builder.build();
final Calendar c = Calendar.getInstance(); binding.editIssueDueDate.setOnClickListener(
int mYear = c.get(Calendar.YEAR); v -> materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER"));
final int mMonth = c.get(Calendar.MONTH);
final int mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = materialDatePicker.addOnPositiveButtonClickListener(
new DatePickerDialog( selection -> {
this, Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
(view, year, monthOfYear, dayOfMonth) -> { calendar.setTimeInMillis(selection);
binding.editIssueDueDate.setText( SimpleDateFormat format =
getString( new SimpleDateFormat(
R.string.setDueDate, "yyyy-MM-dd", new Locale(tinyDB.getString("locale")));
year, String formattedDate = format.format(calendar.getTime());
(monthOfYear + 1), binding.editIssueDueDate.setText(formattedDate);
dayOfMonth)); });
currentDate = new Date(year - 1900, monthOfYear, dayOfMonth);
},
mYear,
mMonth,
mDay);
datePickerDialog.show();
} else if (v == binding.editIssueButton) {
processEditIssue();
}
} }
private void getIssue( private void getIssue(
@ -431,8 +402,6 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
} }
}, },
500); 500);
enableProcessButton();
} }
} }
@ -454,35 +423,27 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe
String dueDate = formatter.format(response.body().getDueDate()); String dueDate = formatter.format(response.body().getDueDate());
binding.editIssueDueDate.setText(dueDate); binding.editIssueDueDate.setText(dueDate);
} }
// enableProcessButton();
} else if (response.code() == 401) { } else if (response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else { } else {
Toasty.error(ctx, getString(R.string.genericError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) {
Log.e("onFailure", t.toString()); // Log.e("onFailure", t.toString());
} }
}); });
} }
private void disableProcessButton() {
binding.editIssueButton.setEnabled(false);
}
private void enableProcessButton() {
binding.editIssueButton.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -21,6 +21,7 @@ import com.vdurmont.emoji.EmojiParser;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.gitnex.tea4j.v2.models.ContentsResponse; import org.gitnex.tea4j.v2.models.ContentsResponse;
@ -60,7 +61,9 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
OutputStream outputStream = OutputStream outputStream =
getContentResolver() getContentResolver()
.openOutputStream(result.getData().getData()); .openOutputStream(
Objects.requireNonNull(
result.getData().getData()));
NotificationCompat.Builder builder = NotificationCompat.Builder builder =
new NotificationCompat.Builder(ctx, ctx.getPackageName()) new NotificationCompat.Builder(ctx, ctx.getPackageName())
@ -108,6 +111,17 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
assert response.body() != null; assert response.body() != null;
builder.setOngoing(false)
.setContentTitle(
getString(
R.string
.fileViewerNotificationTitleFinished))
.setContentText(
getString(
R.string
.fileViewerNotificationDescriptionFinished,
file.getName()));
AppUtil.copyProgress( AppUtil.copyProgress(
response.body().byteStream(), response.body().byteStream(),
outputStream, outputStream,
@ -120,19 +134,10 @@ public class FileViewActivity extends BaseActivity implements BottomSheetListene
builder.build()); builder.build());
}); });
builder.setContentTitle(
getString(
R.string
.fileViewerNotificationTitleFinished))
.setContentText(
getString(
R.string
.fileViewerNotificationDescriptionFinished,
file.getName()));
} catch (IOException ignored) { } catch (IOException ignored) {
builder.setContentTitle( builder.setOngoing(false)
.setContentTitle(
getString( getString(
R.string R.string
.fileViewerNotificationTitleFailed)) .fileViewerNotificationTitleFailed))

View File

@ -1,5 +1,8 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Color; import android.graphics.Color;
@ -21,22 +24,30 @@ import android.widget.ScrollView;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
import androidx.core.widget.ImageViewCompat; import androidx.core.widget.ImageViewCompat;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import okhttp3.ResponseBody;
import org.apache.commons.io.FilenameUtils;
import org.gitnex.tea4j.v2.models.Attachment;
import org.gitnex.tea4j.v2.models.EditIssueOption; import org.gitnex.tea4j.v2.models.EditIssueOption;
import org.gitnex.tea4j.v2.models.Issue; import org.gitnex.tea4j.v2.models.Issue;
import org.gitnex.tea4j.v2.models.IssueLabelsOption; import org.gitnex.tea4j.v2.models.IssueLabelsOption;
@ -55,6 +66,7 @@ import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityIssueDetailBinding; import org.mian.gitnex.databinding.ActivityIssueDetailBinding;
import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding; import org.mian.gitnex.databinding.CustomAssigneesSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomImageViewDialogBinding;
import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding; import org.mian.gitnex.databinding.CustomLabelsSelectionDialogBinding;
import org.mian.gitnex.databinding.CustomPrInfoDialogBinding; import org.mian.gitnex.databinding.CustomPrInfoDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment; import org.mian.gitnex.fragments.BottomSheetReplyFragment;
@ -64,12 +76,14 @@ import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.ClickListener;
import org.mian.gitnex.helpers.ColorInverter; import org.mian.gitnex.helpers.ColorInverter;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.LabelWidthCalculator; import org.mian.gitnex.helpers.LabelWidthCalculator;
import org.mian.gitnex.helpers.Markdown; import org.mian.gitnex.helpers.Markdown;
import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.RoundedTransformation;
import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.helpers.TimeHelper;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.notifications.Notifications;
import org.mian.gitnex.structs.BottomSheetListener; import org.mian.gitnex.structs.BottomSheetListener;
import org.mian.gitnex.viewmodels.IssueCommentsViewModel; import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
import org.mian.gitnex.views.ReactionList; import org.mian.gitnex.views.ReactionList;
@ -110,6 +124,13 @@ public class IssueDetailActivity extends BaseActivity
private boolean loadingFinishedIssue = false; private boolean loadingFinishedIssue = false;
private boolean loadingFinishedPr = false; private boolean loadingFinishedPr = false;
private boolean loadingFinishedRepo = false; private boolean loadingFinishedRepo = false;
private String filename;
private Long filesize;
private String filehash;
private String instanceUrlOnly;
private String token;
private int page = 1;
public ActivityResultLauncher<Intent> editIssueLauncher = public ActivityResultLauncher<Intent> editIssueLauncher =
registerForActivityResult( registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), new ActivityResultContracts.StartActivityForResult(),
@ -129,7 +150,116 @@ public class IssueDetailActivity extends BaseActivity
} }
} }
}); });
private int page = 1;
public ActivityResultLauncher<Intent> downloadAttachmentLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
assert result.getData() != null;
try {
OutputStream outputStream =
getContentResolver()
.openOutputStream(
Objects.requireNonNull(
result.getData().getData()));
NotificationCompat.Builder builder =
new NotificationCompat.Builder(ctx, ctx.getPackageName())
.setContentTitle(
getString(
R.string
.fileViewerNotificationTitleStarted))
.setContentText(
getString(
R.string
.fileViewerNotificationDescriptionStarted,
filename))
.setSmallIcon(R.drawable.gitnex_transparent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setChannelId(
Constants.downloadNotificationChannelId)
.setProgress(100, 0, false)
.setOngoing(true);
int notificationId = Notifications.uniqueNotificationId(ctx);
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, builder.build());
Thread thread =
new Thread(
() -> {
try {
Call<ResponseBody> call =
RetrofitClient.getWebInterface(
ctx,
instanceUrlOnly)
.getAttachment(filehash);
Response<ResponseBody> response =
call.execute();
assert response.body() != null;
builder.setOngoing(false)
.setContentTitle(
getString(
R.string
.fileViewerNotificationTitleFinished))
.setContentText(
getString(
R.string
.fileViewerNotificationDescriptionFinished,
filename));
AppUtil.copyProgress(
response.body().byteStream(),
outputStream,
filesize,
progress -> {
builder.setProgress(
100, progress, false);
notificationManager.notify(
notificationId,
builder.build());
});
} catch (IOException ignored) {
builder.setOngoing(false)
.setContentTitle(
getString(
R.string
.fileViewerNotificationTitleFailed))
.setContentText(
getString(
R.string
.fileViewerNotificationDescriptionFailed,
filename));
} finally {
builder.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(
notificationId, builder.build());
}
});
thread.start();
} catch (IOException ignored) {
}
}
});
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -148,6 +278,11 @@ public class IssueDetailActivity extends BaseActivity
Objects.requireNonNull(getSupportActionBar()).setTitle(repoName); Objects.requireNonNull(getSupportActionBar()).setTitle(repoName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
String instanceUrl = ((BaseActivity) ctx).getAccount().getAccount().getInstanceUrl();
instanceUrlOnly = instanceUrl.substring(0, instanceUrl.lastIndexOf("api/v1/"));
token = ((BaseActivity) ctx).getAccount().getAccount().getToken();
materialAlertDialogBuilder = materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx, R.style.ThemeOverlay_Material3_Dialog_Alert); new MaterialAlertDialogBuilder(ctx, R.style.ThemeOverlay_Material3_Dialog_Alert);
@ -191,10 +326,11 @@ public class IssueDetailActivity extends BaseActivity
viewBinding.toolbarTitle.setText(repoName); viewBinding.toolbarTitle.setText(repoName);
getSingleIssue(repoOwner, repoName, issueIndex); getSingleIssue(repoOwner, repoName, issueIndex);
getAttachments();
fetchDataAsync(repoOwner, repoName, issueIndex); fetchDataAsync(repoOwner, repoName, issueIndex);
if (getIntent().getStringExtra("openPrDiff") != null if (getIntent().getStringExtra("openPrDiff") != null
&& getIntent().getStringExtra("openPrDiff").equals("true")) { && Objects.equals(getIntent().getStringExtra("openPrDiff"), "true")) {
startActivity(issue.getIntent(ctx, DiffActivity.class)); startActivity(issue.getIntent(ctx, DiffActivity.class));
} }
} }
@ -456,7 +592,7 @@ public class IssueDetailActivity extends BaseActivity
if (issue.hasIssue() if (issue.hasIssue()
&& getIntent().getStringExtra("openedFromLink") != null && getIntent().getStringExtra("openedFromLink") != null
&& getIntent().getStringExtra("openedFromLink").equals("true")) { && Objects.equals(getIntent().getStringExtra("openedFromLink"), "true")) {
Intent intent = issue.getRepository().getIntent(ctx, RepoDetailActivity.class); Intent intent = issue.getRepository().getIntent(ctx, RepoDetailActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent); startActivity(intent);
@ -624,7 +760,6 @@ public class IssueDetailActivity extends BaseActivity
} else if (response.code() == 401) { } else if (response.code() == 401) {
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 404) { } else if (response.code() == 404) {
Toasty.warning(ctx, getResources().getString(R.string.noDataFound)); Toasty.warning(ctx, getResources().getString(R.string.noDataFound));
@ -636,7 +771,6 @@ public class IssueDetailActivity extends BaseActivity
public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Issue> call, @NonNull Throwable t) {
viewBinding.progressBar.setVisibility(View.GONE); viewBinding.progressBar.setVisibility(View.GONE);
Log.e("onFailure", t.toString());
} }
}); });
@ -1104,4 +1238,135 @@ public class IssueDetailActivity extends BaseActivity
} }
}); });
} }
private void getAttachments() {
Call<List<Attachment>> call =
RetrofitClient.getApiInterface(ctx)
.issueListIssueAttachments(
issue.getRepository().getOwner(),
issue.getRepository().getName(),
(long) issueIndex);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Attachment>> call,
@NonNull retrofit2.Response<List<Attachment>> response) {
List<Attachment> attachment = response.body();
if (response.code() == 200) {
assert attachment != null;
if (attachment.size() > 0) {
viewBinding.attachmentFrame.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams paramsAttachment =
new LinearLayout.LayoutParams(96, 96);
paramsAttachment.setMargins(0, 0, 48, 0);
for (int i = 0; i < attachment.size(); i++) {
ImageView attachmentView = new ImageView(ctx);
MaterialCardView materialCardView = new MaterialCardView(ctx);
materialCardView.setLayoutParams(paramsAttachment);
materialCardView.setStrokeWidth(0);
materialCardView.setCardBackgroundColor(Color.TRANSPARENT);
if (Arrays.asList(
"bmp", "gif", "jpg", "jpeg", "png", "webp",
"heic", "heif")
.contains(
FilenameUtils.getExtension(
attachment.get(i).getName())
.toLowerCase())) {
PicassoService.getInstance(ctx)
.get()
.load(
attachment.get(i).getBrowserDownloadUrl()
+ "?token="
+ token)
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop()
.error(R.drawable.ic_close)
.into(attachmentView);
viewBinding.attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI1 = i;
materialCardView.setOnClickListener(
v1 ->
imageViewDialog(
attachment
.get(finalI1)
.getBrowserDownloadUrl()));
} else {
attachmentView.setImageResource(
R.drawable.ic_file_download);
attachmentView.setPadding(4, 4, 4, 4);
viewBinding.attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI = i;
materialCardView.setOnClickListener(
v1 -> {
filesize = attachment.get(finalI).getSize();
filename = attachment.get(finalI).getName();
filehash = attachment.get(finalI).getUuid();
requestFileDownload();
});
}
}
} else {
viewBinding.attachmentFrame.setVisibility(View.GONE);
}
}
}
@Override
public void onFailure(
@NonNull Call<List<Attachment>> call, @NonNull Throwable t) {}
});
}
private void requestFileDownload() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_TITLE, filename);
intent.setType("*/*");
downloadAttachmentLauncher.launch(intent);
}
private void imageViewDialog(String url) {
CustomImageViewDialogBinding imageViewDialogBinding =
CustomImageViewDialogBinding.inflate(LayoutInflater.from(ctx));
View view = imageViewDialogBinding.getRoot();
materialAlertDialogBuilder.setView(view);
materialAlertDialogBuilder.setNeutralButton(getString(R.string.close), null);
PicassoService.getInstance(ctx)
.get()
.load(url + "?token=" + token)
.placeholder(R.drawable.loader_animated)
.resize(0, 1600)
.onlyScaleDown()
.centerCrop()
.error(R.drawable.ic_close)
.into(imageViewDialogBinding.imageView);
materialAlertDialogBuilder.create().show();
}
} }

View File

@ -30,7 +30,7 @@ import org.mian.gitnex.databinding.ActivityLoginBinding;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.NetworkStatusObserver; import org.mian.gitnex.helpers.NetworkStatusObserver;
import org.mian.gitnex.helpers.PathsHelper; 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.UrlHelper;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.structs.Protocol; import org.mian.gitnex.structs.Protocol;
@ -88,7 +88,10 @@ public class LoginActivity extends BaseActivity {
selectedProtocol = String.valueOf(parent.getItemAtPosition(position)); selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
if (selectedProtocol.equals(String.valueOf(Protocol.HTTP))) { if (selectedProtocol.equals(String.valueOf(Protocol.HTTP))) {
Toasty.warning(ctx, getResources().getString(R.string.protocolError)); SnackBar.warning(
ctx,
findViewById(android.R.id.content),
getString(R.string.protocolError));
} }
}); });
@ -137,10 +140,10 @@ public class LoginActivity extends BaseActivity {
disableProcessButton(); disableProcessButton();
loginButton.setText( loginButton.setText(
getResources().getString(R.string.btnLogin)); getResources().getString(R.string.btnLogin));
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.checkNetConnection)); getString(R.string.checkNetConnection));
} }
})); }));
@ -159,7 +162,10 @@ public class LoginActivity extends BaseActivity {
if (selectedProtocol == null) { if (selectedProtocol == null) {
Toasty.error(ctx, getResources().getString(R.string.protocolEmptyError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.protocolEmptyError));
enableProcessButton(); enableProcessButton();
return; return;
} }
@ -197,7 +203,8 @@ public class LoginActivity extends BaseActivity {
if (instanceUrlET.getText().toString().equals("")) { if (instanceUrlET.getText().toString().equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldURL)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.emptyFieldURL));
enableProcessButton(); enableProcessButton();
return; return;
} }
@ -206,19 +213,28 @@ public class LoginActivity extends BaseActivity {
if (otpCode.length() != 0 && otpCode.length() != 6) { if (otpCode.length() != 0 && otpCode.length() != 6) {
Toasty.warning(ctx, getResources().getString(R.string.loginOTPTypeError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.loginOTPTypeError));
enableProcessButton(); enableProcessButton();
return; return;
} }
if (loginUid.equals("")) { if (loginUid.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldUsername)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.emptyFieldUsername));
enableProcessButton(); enableProcessButton();
return; return;
} }
if (loginPass.equals("")) { if (loginPass.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.emptyFieldPassword)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.emptyFieldPassword));
enableProcessButton(); enableProcessButton();
return; return;
} }
@ -234,7 +250,10 @@ public class LoginActivity extends BaseActivity {
if (loginToken.equals("")) { if (loginToken.equals("")) {
Toasty.error(ctx, getResources().getString(R.string.loginTokenError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.loginTokenError));
enableProcessButton(); enableProcessButton();
return; return;
} }
@ -245,7 +264,8 @@ public class LoginActivity extends BaseActivity {
} catch (Exception e) { } catch (Exception e) {
Toasty.error(ctx, getResources().getString(R.string.malformedUrl)); SnackBar.error(
ctx, findViewById(android.R.id.content), getString(R.string.malformedUrl));
enableProcessButton(); enableProcessButton();
} }
} }
@ -331,8 +351,10 @@ public class LoginActivity extends BaseActivity {
if (!Version.valid(version.getVersion())) { if (!Version.valid(version.getVersion())) {
Toasty.error( SnackBar.error(
ctx, getResources().getString(R.string.versionUnknown)); ctx,
findViewById(android.R.id.content),
getString(R.string.versionUnknown));
enableProcessButton(); enableProcessButton();
return; return;
} }
@ -376,9 +398,10 @@ public class LoginActivity extends BaseActivity {
login(loginType, loginUid, loginPass, loginOTP, loginToken); login(loginType, loginUid, loginPass, loginOTP, loginToken);
} else { } else {
Toasty.warning( SnackBar.warning(
ctx, ctx,
getResources().getString(R.string.versionUnsupportedNew)); findViewById(android.R.id.content),
getString(R.string.versionUnsupportedNew));
login(loginType, loginUid, loginPass, loginOTP, loginToken); login(loginType, loginUid, loginPass, loginOTP, loginToken);
} }
@ -412,8 +435,10 @@ public class LoginActivity extends BaseActivity {
public void onFailure( public void onFailure(
@NonNull Call<ServerVersion> callVersion, @NonNull Throwable t) { @NonNull Call<ServerVersion> callVersion, @NonNull Throwable t) {
Toasty.error( SnackBar.error(
ctx, getResources().getString(R.string.genericServerResponseError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -475,17 +500,17 @@ public class LoginActivity extends BaseActivity {
finish(); finish();
break; break;
case 401: case 401:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources().getString(R.string.unauthorizedApiError)); findViewById(android.R.id.content),
getString(R.string.unauthorizedApiError));
enableProcessButton(); enableProcessButton();
break; break;
default: default:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(R.string.genericApiError, response.code()));
R.string.genericApiError, response.code()));
enableProcessButton(); enableProcessButton();
} }
} }
@ -493,7 +518,10 @@ public class LoginActivity extends BaseActivity {
@Override @Override
public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -580,13 +608,12 @@ public class LoginActivity extends BaseActivity {
tokenName); tokenName);
} else { } else {
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(
R.string R.string.genericApiError,
.genericApiError, response.code()));
response.code()));
enableProcessButton(); enableProcessButton();
} }
} }
@ -596,12 +623,10 @@ public class LoginActivity extends BaseActivity {
@NonNull Call<Void> delToken, @NonNull Call<Void> delToken,
@NonNull Throwable t) { @NonNull Throwable t) {
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(R.string.malformedJson));
R.string
.malformedJson));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -612,10 +637,10 @@ public class LoginActivity extends BaseActivity {
setupToken(loginUid, loginPass, loginOTP, tokenName); setupToken(loginUid, loginPass, loginOTP, tokenName);
} else { } else {
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.genericApiError, response.code())); getString(R.string.genericApiError, response.code()));
enableProcessButton(); enableProcessButton();
} }
} }
@ -624,7 +649,10 @@ public class LoginActivity extends BaseActivity {
public void onFailure( public void onFailure(
@NonNull Call<List<AccessToken>> call, @NonNull Throwable t) { @NonNull Call<List<AccessToken>> call, @NonNull Throwable t) {
Toasty.error(ctx, getResources().getString(R.string.malformedJson)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.malformedJson));
enableProcessButton(); enableProcessButton();
} }
}); });
@ -750,22 +778,21 @@ public class LoginActivity extends BaseActivity {
finish(); finish();
break; break;
case 401: case 401:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(
R.string R.string
.unauthorizedApiError)); .unauthorizedApiError));
enableProcessButton(); enableProcessButton();
break; break;
default: default:
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(
R.string R.string.genericApiError,
.genericApiError, response.code()));
response.code()));
enableProcessButton(); enableProcessButton();
} }
} }
@ -775,22 +802,20 @@ public class LoginActivity extends BaseActivity {
@NonNull Call<User> call, @NonNull Call<User> call,
@NonNull Throwable t) { @NonNull Throwable t) {
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.genericError)); getString(R.string.genericError));
enableProcessButton(); enableProcessButton();
} }
}); });
} }
} else if (responseCreate.code() == 500) { } else if (responseCreate.code() == 500) {
Toasty.error( SnackBar.error(
ctx, ctx,
getResources() findViewById(android.R.id.content),
.getString( getString(R.string.genericApiError, responseCreate.code()));
R.string.genericApiError,
responseCreate.code()));
enableProcessButton(); enableProcessButton();
} }
} }
@ -799,7 +824,10 @@ public class LoginActivity extends BaseActivity {
public void onFailure( public void onFailure(
@NonNull Call<AccessToken> createUserToken, @NonNull Throwable t) { @NonNull Call<AccessToken> createUserToken, @NonNull Throwable t) {
Toasty.error(ctx, ctx.getString(R.string.genericServerResponseError)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.genericServerResponseError));
} }
}); });
} }

View File

@ -553,7 +553,6 @@ public class MainActivity extends BaseActivity
giteaVersion(); giteaVersion();
serverPageLimitSettings(); serverPageLimitSettings();
noConnection = false;
} }
}, },
1500); 1500);

View File

@ -1,11 +1,11 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,9 +17,8 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.ActivityMergePullRequestBinding; import org.mian.gitnex.databinding.ActivityMergePullRequestBinding;
import org.mian.gitnex.fragments.PullRequestsFragment; import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.MergePullRequestSpinner; import org.mian.gitnex.helpers.MergePullRequestSpinner;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.helpers.contexts.IssueContext;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -29,11 +28,9 @@ import retrofit2.Callback;
*/ */
public class MergePullRequestActivity extends BaseActivity { public class MergePullRequestActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private IssueContext issue; private IssueContext issue;
private ActivityMergePullRequestBinding viewBinding; private ActivityMergePullRequestBinding viewBinding;
private String Do; private String Do;
private final View.OnClickListener mergePullRequest = v -> processMergePullRequest();
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@Override @Override
@ -46,26 +43,22 @@ public class MergePullRequestActivity extends BaseActivity {
issue = IssueContext.fromIntent(getIntent()); issue = IssueContext.fromIntent(getIntent());
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
viewBinding.mergeTitle.requestFocus();
assert imm != null;
imm.showSoftInput(viewBinding.mergeTitle, InputMethodManager.SHOW_IMPLICIT);
setMergeAdapter(); setMergeAdapter();
if (!issue.getPullRequest().getTitle().isEmpty()) { if (!issue.getPullRequest().getTitle().isEmpty()) {
viewBinding.topAppBar.setTitle(issue.getPullRequest().getTitle());
viewBinding.toolbarTitle.setText(issue.getPullRequest().getTitle());
viewBinding.mergeTitle.setText( viewBinding.mergeTitle.setText(
issue.getPullRequest().getTitle() + " (#" + issue.getIssueIndex() + ")"); issue.getPullRequest().getTitle() + " (#" + issue.getIssueIndex() + ")");
} }
initCloseListener(); viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
viewBinding.close.setOnClickListener(onClickListener);
MenuItem attachment = viewBinding.topAppBar.getMenu().getItem(0);
MenuItem markdown = viewBinding.topAppBar.getMenu().getItem(1);
MenuItem create = viewBinding.topAppBar.getMenu().getItem(2);
attachment.setVisible(false);
markdown.setVisible(false);
create.setTitle(getString(R.string.mergePullRequestButtonText));
// if gitea version is greater/equal(1.12.0) than user installed version // if gitea version is greater/equal(1.12.0) than user installed version
// (installed.higherOrEqual(compareVer)) // (installed.higherOrEqual(compareVer))
@ -75,36 +68,37 @@ public class MergePullRequestActivity extends BaseActivity {
} }
if (!issue.getPullRequest().isMergeable()) { if (!issue.getPullRequest().isMergeable()) {
disableProcessButton();
viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE); viewBinding.mergeInfoDisabledMessage.setVisibility(View.VISIBLE);
create.setVisible(false);
} else { } else {
viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE); viewBinding.mergeInfoDisabledMessage.setVisibility(View.GONE);
create.setVisible(true);
} }
if (issue.prIsFork()) { if (issue.prIsFork()) {
viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE); viewBinding.deleteBranchForkInfo.setVisibility(View.VISIBLE);
} else { } else {
viewBinding.deleteBranchForkInfo.setVisibility(View.GONE); viewBinding.deleteBranchForkInfo.setVisibility(View.GONE);
} }
if (!connToInternet) {
disableProcessButton();
} else {
viewBinding.mergeButton.setOnClickListener(mergePullRequest);
}
if (!(issue.getPullRequest().getHead().getRepo() != null if (!(issue.getPullRequest().getHead().getRepo() != null
? issue.getPullRequest().getHead().getRepo().getPermissions().isPush() ? issue.getPullRequest().getHead().getRepo().getPermissions().isPush()
: false)) { : false)) {
viewBinding.deleteBranch.setVisibility(View.GONE); viewBinding.deleteBranch.setVisibility(View.GONE);
viewBinding.deleteBranchForkInfo.setVisibility(View.GONE); viewBinding.deleteBranchForkInfo.setVisibility(View.GONE);
} }
viewBinding.topAppBar.setOnMenuItemClickListener(
menuItem -> {
int id = menuItem.getItemId();
if (id == R.id.create) {
processMergePullRequest();
return true;
} else {
return super.onOptionsItemSelected(menuItem);
}
});
} }
private void setMergeAdapter() { private void setMergeAdapter() {
@ -140,11 +134,6 @@ public class MergePullRequestActivity extends BaseActivity {
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
private void processMergePullRequest() { private void processMergePullRequest() {
String mergePRDesc = String mergePRDesc =
@ -152,20 +141,14 @@ public class MergePullRequestActivity extends BaseActivity {
String mergePRTitle = Objects.requireNonNull(viewBinding.mergeTitle.getText()).toString(); String mergePRTitle = Objects.requireNonNull(viewBinding.mergeTitle.getText()).toString();
boolean deleteBranch = viewBinding.deleteBranch.isChecked(); boolean deleteBranch = viewBinding.deleteBranch.isChecked();
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
if (!connToInternet) {
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
return;
}
if (Do == null) { if (Do == null) {
Toasty.error(ctx, getResources().getString(R.string.selectMergeStrategy)); SnackBar.error(
ctx,
findViewById(android.R.id.content),
getString(R.string.selectMergeStrategy));
} else { } else {
disableProcessButton();
mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch); mergeFunction(Do, mergePRDesc, mergePRTitle, deleteBranch);
} }
} }
@ -237,49 +220,46 @@ public class MergePullRequestActivity extends BaseActivity {
} }
} }
Toasty.success(ctx, getString(R.string.mergePRSuccessMsg)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.mergePRSuccessMsg));
Intent result = new Intent(); Intent result = new Intent();
PullRequestsFragment.resumePullRequests = true; PullRequestsFragment.resumePullRequests = true;
IssueDetailActivity.singleIssueUpdate = true; IssueDetailActivity.singleIssueUpdate = true;
RepoDetailActivity.updateRepo = true; RepoDetailActivity.updateRepo = true;
setResult(200, result); setResult(200, result);
finish(); new Handler().postDelayed(() -> finish(), 3000);
} else if (response.code() == 401) { } else if (response.code() == 401) {
enableProcessButton();
AlertDialogs.authorizationTokenRevokedDialog(ctx); AlertDialogs.authorizationTokenRevokedDialog(ctx);
} else if (response.code() == 404) { } else if (response.code() == 404) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.mergePR404ErrorMsg)); ctx,
findViewById(android.R.id.content),
getString(R.string.mergePR404ErrorMsg));
} else if (response.code() == 405) { } else if (response.code() == 405) {
enableProcessButton(); SnackBar.error(
Toasty.warning(ctx, getString(R.string.mergeNotAllowed)); ctx,
findViewById(android.R.id.content),
getString(R.string.mergeNotAllowed));
} else { } else {
enableProcessButton(); SnackBar.error(
Toasty.error(ctx, getString(R.string.genericError)); ctx,
findViewById(android.R.id.content),
getString(R.string.genericError));
} }
} }
@Override @Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {}
enableProcessButton();
}
}); });
} }
private void disableProcessButton() {
viewBinding.mergeButton.setEnabled(false);
}
private void enableProcessButton() {
viewBinding.mergeButton.setEnabled(true);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();

View File

@ -41,6 +41,7 @@ public class ProfileActivity extends BaseActivity implements BottomSheetListener
private String username; private String username;
private boolean following; private boolean following;
public ViewPager2 viewPager;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -64,7 +65,7 @@ public class ProfileActivity extends BaseActivity implements BottomSheetListener
Objects.requireNonNull(getSupportActionBar()).setTitle(username); Objects.requireNonNull(getSupportActionBar()).setTitle(username);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ViewPager2 viewPager = findViewById(R.id.profileContainer); viewPager = findViewById(R.id.profileContainer);
viewPager.setOffscreenPageLimit(1); viewPager.setOffscreenPageLimit(1);
TabLayout tabLayout = findViewById(R.id.tabs); TabLayout tabLayout = findViewById(R.id.tabs);

View File

@ -664,7 +664,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetListe
mainIntent.removeExtra("goToSection"); mainIntent.removeExtra("goToSection");
mainIntent.removeExtra("goToSectionType"); mainIntent.removeExtra("goToSectionType");
switch (goToSectionType) { switch (Objects.requireNonNull(goToSectionType)) {
case "branchesList": case "branchesList":
viewPager.setCurrentItem(1); viewPager.setCurrentItem(1);
chooseBranch(); chooseBranch();

View File

@ -1,14 +1,10 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.TimePicker;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.timepicker.MaterialTimePicker;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Locale; import java.util.Locale;
import org.mian.gitnex.R; import org.mian.gitnex.R;
@ -16,8 +12,8 @@ import org.mian.gitnex.databinding.ActivitySettingsAppearanceBinding;
import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.FontsOverride; import org.mian.gitnex.helpers.FontsOverride;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Toasty;
/** /**
* @author M M Arif * @author M M Arif
@ -28,7 +24,6 @@ public class SettingsAppearanceActivity extends BaseActivity {
private static int customFontSelectedChoice = 0; private static int customFontSelectedChoice = 0;
private static String[] themeList; private static String[] themeList;
private static int themeSelectedChoice = 0; private static int themeSelectedChoice = 0;
private View.OnClickListener onClickListener;
private static int langSelectedChoice = 0; private static int langSelectedChoice = 0;
private static String[] fragmentTabsAnimationList; private static String[] fragmentTabsAnimationList;
private static int fragmentTabsAnimationSelectedChoice = 0; private static int fragmentTabsAnimationSelectedChoice = 0;
@ -58,8 +53,7 @@ public class SettingsAppearanceActivity extends BaseActivity {
themeList = getResources().getStringArray(R.array.themes); themeList = getResources().getStringArray(R.array.themes);
} }
initCloseListener(); activitySettingsAppearanceBinding.topAppBar.setNavigationOnClickListener(v -> finish());
activitySettingsAppearanceBinding.close.setOnClickListener(onClickListener);
String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute")); String lightMinute = String.valueOf(tinyDB.getInt("lightThemeTimeMinute"));
String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour")); String lightHour = String.valueOf(tinyDB.getInt("lightThemeTimeHour"));
@ -112,7 +106,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
activitySettingsAppearanceBinding.switchCounterBadge.setOnCheckedChangeListener( activitySettingsAppearanceBinding.switchCounterBadge.setOnCheckedChangeListener(
(buttonView, isChecked) -> { (buttonView, isChecked) -> {
tinyDB.putBoolean("enableCounterBadges", isChecked); tinyDB.putBoolean("enableCounterBadges", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
activitySettingsAppearanceBinding.counterBadgeFrame.setOnClickListener( activitySettingsAppearanceBinding.counterBadgeFrame.setOnClickListener(
v -> v ->
@ -126,7 +123,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
activitySettingsAppearanceBinding.switchLabelsInListBadge.setOnCheckedChangeListener( activitySettingsAppearanceBinding.switchLabelsInListBadge.setOnCheckedChangeListener(
(buttonView, isChecked) -> { (buttonView, isChecked) -> {
tinyDB.putBoolean("showLabelsInList", isChecked); tinyDB.putBoolean("showLabelsInList", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
activitySettingsAppearanceBinding.labelsInListFrame.setOnClickListener( activitySettingsAppearanceBinding.labelsInListFrame.setOnClickListener(
v -> v ->
@ -153,26 +153,20 @@ public class SettingsAppearanceActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
activitySettingsAppearanceBinding.lightThemeTimeSelectionFrame.setOnClickListener( activitySettingsAppearanceBinding.lightThemeTimeSelectionFrame.setOnClickListener(
view -> { view -> lightTimePicker());
LightTimePicker timePicker = new LightTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
activitySettingsAppearanceBinding.darkThemeTimeSelectionFrame.setOnClickListener( activitySettingsAppearanceBinding.darkThemeTimeSelectionFrame.setOnClickListener(
view -> { view -> darkTimePicker());
DarkTimePicker timePicker = new DarkTimePicker();
timePicker.show(getSupportFragmentManager(), "timePicker");
});
// custom font dialog // custom font dialog
activitySettingsAppearanceBinding.customFontFrame.setOnClickListener( activitySettingsAppearanceBinding.customFontFrame.setOnClickListener(
@ -196,10 +190,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss(); dialogInterfaceCustomFont.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
appCtx.getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -228,10 +222,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceCustomFont.dismiss(); dialogInterfaceCustomFont.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
appCtx.getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -239,9 +233,9 @@ public class SettingsAppearanceActivity extends BaseActivity {
// language selector dialog // language selector dialog
activitySettingsAppearanceBinding.helpTranslate.setOnClickListener( activitySettingsAppearanceBinding.helpTranslate.setOnClickListener(
v12 -> { v12 ->
AppUtil.openUrlInBrowser(this, getResources().getString(R.string.crowdInLink)); AppUtil.openUrlInBrowser(
}); this, getResources().getString(R.string.crowdInLink)));
langSelectedChoice = tinyDB.getInt("langId"); langSelectedChoice = tinyDB.getInt("langId");
activitySettingsAppearanceBinding.tvLanguageSelected.setText( activitySettingsAppearanceBinding.tvLanguageSelected.setText(
@ -267,10 +261,10 @@ public class SettingsAppearanceActivity extends BaseActivity {
SettingsFragment.refreshParent = true; SettingsFragment.refreshParent = true;
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterface.dismiss(); dialogInterface.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
this.recreate(); this.recreate();
}); });
@ -278,62 +272,56 @@ public class SettingsAppearanceActivity extends BaseActivity {
}); });
} }
private void initCloseListener() { public void lightTimePicker() {
onClickListener = view -> finish();
TinyDB db = TinyDB.getInstance(ctx);
int hour = db.getInt("lightThemeTimeHour");
int minute = db.getInt("lightThemeTimeMinute");
MaterialTimePicker materialTimePicker =
new MaterialTimePicker.Builder().setHour(hour).setMinute(minute).build();
materialTimePicker.addOnPositiveButtonClickListener(
selection -> {
db.putInt("lightThemeTimeHour", materialTimePicker.getHour());
db.putInt("lightThemeTimeMinute", materialTimePicker.getMinute());
SettingsFragment.refreshParent = true;
overridePendingTransition(0, 0);
SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
recreate();
});
materialTimePicker.show(getSupportFragmentManager(), "fragmentManager");
} }
public static class LightTimePicker extends DialogFragment public void darkTimePicker() {
implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext()); TinyDB db = TinyDB.getInstance(ctx);
@NonNull @Override int hour = db.getInt("darkThemeTimeHour");
public Dialog onCreateDialog(Bundle savedInstanceState) { int minute = db.getInt("darkThemeTimeMinute");
int hour = db.getInt("lightThemeTimeHour");
int minute = db.getInt("lightThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true); MaterialTimePicker materialTimePicker =
} new MaterialTimePicker.Builder().setHour(hour).setMinute(minute).build();
@Override materialTimePicker.addOnPositiveButtonClickListener(
public void onTimeSet(TimePicker view, int hourOfDay, int minute) { selection -> {
db.putInt("lightThemeTimeHour", hourOfDay); db.putInt("darkThemeTimeHour", materialTimePicker.getHour());
db.putInt("lightThemeTimeMinute", minute); db.putInt("darkThemeTimeMinute", materialTimePicker.getMinute());
SettingsFragment.refreshParent = true; SettingsFragment.refreshParent = true;
requireActivity().overridePendingTransition(0, 0); overridePendingTransition(0, 0);
this.dismiss(); SnackBar.success(
Toasty.success( ctx,
requireActivity().getApplicationContext(), findViewById(android.R.id.content),
requireContext().getResources().getString(R.string.settingsSave)); getString(R.string.settingsSave));
requireActivity().recreate(); recreate();
} });
}
public static class DarkTimePicker extends DialogFragment materialTimePicker.show(getSupportFragmentManager(), "fragmentManager");
implements TimePickerDialog.OnTimeSetListener {
TinyDB db = TinyDB.getInstance(getContext());
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int hour = db.getInt("darkThemeTimeHour");
int minute = db.getInt("darkThemeTimeMinute");
return new TimePickerDialog(getActivity(), this, hour, minute, true);
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
db.putInt("darkThemeTimeHour", hourOfDay);
db.putInt("darkThemeTimeMinute", minute);
SettingsFragment.refreshParent = true;
requireActivity().overridePendingTransition(0, 0);
this.dismiss();
Toasty.success(
requireActivity().getApplicationContext(),
requireContext().getResources().getString(R.string.settingsSave));
requireActivity().recreate();
}
} }
private static String getLanguageDisplayName(String langCode) { private static String getLanguageDisplayName(String langCode) {

View File

@ -6,7 +6,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsCodeEditorBinding; import org.mian.gitnex.databinding.ActivitySettingsCodeEditorBinding;
import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
/** /**
* @author M M Arif * @author M M Arif
@ -15,7 +15,6 @@ public class SettingsCodeEditorActivity extends BaseActivity {
private static String[] colorList; private static String[] colorList;
private static int colorSelectedChoice = 0; private static int colorSelectedChoice = 0;
private View.OnClickListener onClickListener;
private static String[] indentationList; private static String[] indentationList;
private static int indentationSelectedChoice = 0; private static int indentationSelectedChoice = 0;
private static String[] indentationTabsList; private static String[] indentationTabsList;
@ -30,8 +29,7 @@ public class SettingsCodeEditorActivity extends BaseActivity {
ActivitySettingsCodeEditorBinding.inflate(getLayoutInflater()); ActivitySettingsCodeEditorBinding.inflate(getLayoutInflater());
setContentView(activitySettingsCodeEditorBinding.getRoot()); setContentView(activitySettingsCodeEditorBinding.getRoot());
initCloseListener(); activitySettingsCodeEditorBinding.topAppBar.setNavigationOnClickListener(v -> finish());
activitySettingsCodeEditorBinding.close.setOnClickListener(onClickListener);
// color selector dialog // color selector dialog
colorList = getResources().getStringArray(R.array.ceColors); colorList = getResources().getStringArray(R.array.ceColors);
@ -56,10 +54,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceColor.dismiss(); dialogInterfaceColor.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -90,10 +88,10 @@ public class SettingsCodeEditorActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceColor.dismiss(); dialogInterfaceColor.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -132,17 +130,13 @@ public class SettingsCodeEditorActivity extends BaseActivity {
this.recreate(); this.recreate();
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
dialogInterfaceColor.dismiss(); dialogInterfaceColor.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
} }

View File

@ -1,14 +1,13 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding; import org.mian.gitnex.databinding.ActivitySettingsGeneralBinding;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
/** /**
* @author M M Arif * @author M M Arif
@ -18,7 +17,6 @@ public class SettingsGeneralActivity extends BaseActivity {
private static int homeScreenSelectedChoice = 0; private static int homeScreenSelectedChoice = 0;
private static int defaultLinkHandlerScreenSelectedChoice = 0; private static int defaultLinkHandlerScreenSelectedChoice = 0;
private ActivitySettingsGeneralBinding viewBinding; private ActivitySettingsGeneralBinding viewBinding;
private View.OnClickListener onClickListener;
private List<String> homeScreenList; private List<String> homeScreenList;
private List<String> linkHandlerDefaultScreen; private List<String> linkHandlerDefaultScreen;
@ -30,8 +28,7 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater()); viewBinding = ActivitySettingsGeneralBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot()); setContentView(viewBinding.getRoot());
initCloseListener(); viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
viewBinding.close.setOnClickListener(onClickListener);
// home screen // home screen
String[] appHomeDefaultScreen = getResources().getStringArray(R.array.appDefaultHomeScreen); String[] appHomeDefaultScreen = getResources().getStringArray(R.array.appDefaultHomeScreen);
@ -118,10 +115,10 @@ public class SettingsGeneralActivity extends BaseActivity {
tinyDB.putInt("homeScreenId", i); tinyDB.putInt("homeScreenId", i);
dialogInterfaceHomeScreen.dismiss(); dialogInterfaceHomeScreen.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -156,10 +153,10 @@ public class SettingsGeneralActivity extends BaseActivity {
tinyDB.putInt("defaultScreenId", i); tinyDB.putInt("defaultScreenId", i);
dialogInterfaceHomeScreen.dismiss(); dialogInterfaceHomeScreen.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
@ -171,7 +168,10 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding.switchTabs.setOnCheckedChangeListener( viewBinding.switchTabs.setOnCheckedChangeListener(
(buttonView, isChecked) -> { (buttonView, isChecked) -> {
tinyDB.putBoolean("useCustomTabs", isChecked); tinyDB.putBoolean("useCustomTabs", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
viewBinding.customTabsFrame.setOnClickListener( viewBinding.customTabsFrame.setOnClickListener(
v -> viewBinding.switchTabs.setChecked(!viewBinding.switchTabs.isChecked())); v -> viewBinding.switchTabs.setChecked(!viewBinding.switchTabs.isChecked()));
@ -185,7 +185,10 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding.commentsDeletionSwitch.setOnCheckedChangeListener( viewBinding.commentsDeletionSwitch.setOnCheckedChangeListener(
(buttonView, isChecked) -> { (buttonView, isChecked) -> {
tinyDB.putBoolean("draftsCommentsDeletionEnabled", isChecked); tinyDB.putBoolean("draftsCommentsDeletionEnabled", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
viewBinding.enableDraftsCommentsDeletion.setOnClickListener( viewBinding.enableDraftsCommentsDeletion.setOnClickListener(
v -> v ->
@ -197,7 +200,10 @@ public class SettingsGeneralActivity extends BaseActivity {
viewBinding.crashReportsSwitch.setOnCheckedChangeListener( viewBinding.crashReportsSwitch.setOnCheckedChangeListener(
(buttonView, isChecked) -> { (buttonView, isChecked) -> {
tinyDB.putBoolean("crashReportingEnabled", isChecked); tinyDB.putBoolean("crashReportingEnabled", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
viewBinding.enableSendReports.setOnClickListener( viewBinding.enableSendReports.setOnClickListener(
v -> v ->
@ -205,8 +211,4 @@ public class SettingsGeneralActivity extends BaseActivity {
!viewBinding.crashReportsSwitch.isChecked())); !viewBinding.crashReportsSwitch.isChecked()));
// crash reports switcher // crash reports switcher
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
} }

View File

@ -1,16 +1,13 @@
package org.mian.gitnex.activities; package org.mian.gitnex.activities;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.NumberPicker;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding; import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.notifications.Notifications; import org.mian.gitnex.notifications.Notifications;
/** /**
@ -20,6 +17,8 @@ import org.mian.gitnex.notifications.Notifications;
public class SettingsNotificationsActivity extends BaseActivity { public class SettingsNotificationsActivity extends BaseActivity {
private ActivitySettingsNotificationsBinding viewBinding; private ActivitySettingsNotificationsBinding viewBinding;
private static String[] pollingDelayList;
private static int pollingDelayListSelectedChoice = 0;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -29,35 +28,13 @@ public class SettingsNotificationsActivity extends BaseActivity {
viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater()); viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot()); setContentView(viewBinding.getRoot());
View.OnClickListener onClickListener = viewClose -> finish(); viewBinding.topAppBar.setNavigationOnClickListener(v -> finish());
viewBinding.close.setOnClickListener(onClickListener);
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( viewBinding.enableNotificationsMode.setChecked(
tinyDB.getBoolean("notificationsEnabled", true)); tinyDB.getBoolean("notificationsEnabled", true));
viewBinding.enableLightsMode.setChecked(
tinyDB.getBoolean("notificationsEnableLights", true));
viewBinding.enableVibrationMode.setChecked(
tinyDB.getBoolean("notificationsEnableVibration", true));
if (!viewBinding.enableNotificationsMode.isChecked()) { if (!viewBinding.enableNotificationsMode.isChecked()) {
AppUtil.setMultiVisibility( AppUtil.setMultiVisibility(View.GONE, viewBinding.pollingDelayFrame);
View.GONE,
viewBinding.chooseColorFrame,
viewBinding.enableLightsFrame,
viewBinding.enableVibrationFrame,
viewBinding.pollingDelayFrame);
}
if (!viewBinding.enableLightsMode.isChecked()) {
viewBinding.chooseColorFrame.setVisibility(View.GONE);
} }
viewBinding.enableNotificationsMode.setOnCheckedChangeListener( viewBinding.enableNotificationsMode.setOnCheckedChangeListener(
@ -66,23 +43,16 @@ public class SettingsNotificationsActivity extends BaseActivity {
if (isChecked) { if (isChecked) {
Notifications.startWorker(ctx); Notifications.startWorker(ctx);
AppUtil.setMultiVisibility( AppUtil.setMultiVisibility(View.VISIBLE, viewBinding.pollingDelayFrame);
View.VISIBLE,
viewBinding.chooseColorFrame,
viewBinding.enableLightsFrame,
viewBinding.enableVibrationFrame,
viewBinding.pollingDelayFrame);
} else { } else {
Notifications.stopWorker(ctx); Notifications.stopWorker(ctx);
AppUtil.setMultiVisibility( AppUtil.setMultiVisibility(View.GONE, viewBinding.pollingDelayFrame);
View.GONE,
viewBinding.chooseColorFrame,
viewBinding.enableLightsFrame,
viewBinding.enableVibrationFrame,
viewBinding.pollingDelayFrame);
} }
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
}); });
viewBinding.enableNotificationsFrame.setOnClickListener( viewBinding.enableNotificationsFrame.setOnClickListener(
v -> v ->
@ -90,93 +60,39 @@ public class SettingsNotificationsActivity extends BaseActivity {
!viewBinding.enableNotificationsMode.isChecked())); !viewBinding.enableNotificationsMode.isChecked()));
// polling delay // polling delay
viewBinding.pollingDelayFrame.setOnClickListener( pollingDelayList = getResources().getStringArray(R.array.notificationsPollingDelay);
v -> { pollingDelayListSelectedChoice = tinyDB.getInt("notificationsPollingDelayId");
NumberPicker numberPicker = new NumberPicker(ctx); viewBinding.pollingDelaySelected.setText(pollingDelayList[pollingDelayListSelectedChoice]);
numberPicker.setMinValue(Constants.minimumPollingDelay);
numberPicker.setMaxValue(Constants.maximumPollingDelay);
numberPicker.setValue(
tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay));
numberPicker.setWrapSelectorWheel(true);
viewBinding.pollingDelayFrame.setOnClickListener(
view -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
.setTitle(R.string.pollingDelayDialogHeaderText) .setTitle(R.string.pollingDelayDialogHeaderText)
.setMessage( .setSingleChoiceItems(
getString(R.string.pollingDelayDialogDescriptionText)) pollingDelayList,
.setCancelable(true) pollingDelayListSelectedChoice,
.setNeutralButton( (dialogInterfaceColor, i) -> {
R.string.cancelButton, pollingDelayListSelectedChoice = i;
(dialog, which) -> dialog.dismiss()) viewBinding.pollingDelaySelected.setText(
.setPositiveButton( pollingDelayList[
getString(R.string.okButton), pollingDelayListSelectedChoice]);
(dialog, which) -> { tinyDB.putInt("notificationsPollingDelayId", i);
tinyDB.putInt(
"pollingDelayMinutes",
numberPicker.getValue());
Notifications.stopWorker(ctx); Notifications.stopWorker(ctx);
Notifications.startWorker(ctx); Notifications.startWorker(ctx);
viewBinding.pollingDelaySelected.setText( SettingsFragment.refreshParent = true;
String.format( this.recreate();
getString( this.overridePendingTransition(0, 0);
R.string dialogInterfaceColor.dismiss();
.pollingDelaySelectedText), SnackBar.success(
numberPicker.getValue())); ctx,
Toasty.success( findViewById(android.R.id.content),
appCtx, getString(R.string.settingsSave));
getResources()
.getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.setView(numberPicker);
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
// lights switcher
viewBinding.enableLightsMode.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
if (!isChecked) {
viewBinding.chooseColorFrame.setVisibility(View.GONE);
} else {
viewBinding.chooseColorFrame.setVisibility(View.VISIBLE);
}
tinyDB.putBoolean("notificationsEnableLights", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
});
viewBinding.enableLightsFrame.setOnClickListener(
v ->
viewBinding.enableLightsMode.setChecked(
!viewBinding.enableLightsMode.isChecked()));
// lights color chooser
viewBinding.chooseColorFrame.setOnClickListener(
v -> {
ColorPicker colorPicker = new ColorPicker(SettingsNotificationsActivity.this);
colorPicker.setColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
colorPicker.setCallback(
color -> {
tinyDB.putInt("notificationsLightColor", color);
viewBinding.chooseColorState.setCardBackgroundColor(color);
colorPicker.dismiss();
Toasty.success(
appCtx, getResources().getString(R.string.settingsSave));
});
colorPicker.show();
});
// vibration switcher
viewBinding.enableVibrationMode.setOnCheckedChangeListener(
(buttonView, isChecked) -> {
tinyDB.putBoolean("notificationsEnableVibration", isChecked);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
});
viewBinding.enableVibrationFrame.setOnClickListener(
v ->
viewBinding.enableVibrationMode.setChecked(
!viewBinding.enableVibrationMode.isChecked()));
} }
} }

View File

@ -6,11 +6,6 @@ import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTI
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.biometric.BiometricManager; import androidx.biometric.BiometricManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.File; import java.io.File;
@ -19,7 +14,7 @@ import org.apache.commons.io.FileUtils;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.databinding.ActivitySettingsSecurityBinding; import org.mian.gitnex.databinding.ActivitySettingsSecurityBinding;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
/** /**
@ -31,7 +26,6 @@ public class SettingsSecurityActivity extends BaseActivity {
private static int cacheSizeDataSelectedChoice = 0; private static int cacheSizeDataSelectedChoice = 0;
private static String[] cacheSizeImagesList; private static String[] cacheSizeImagesList;
private static int cacheSizeImagesSelectedChoice = 0; private static int cacheSizeImagesSelectedChoice = 0;
private View.OnClickListener onClickListener;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -42,33 +36,15 @@ public class SettingsSecurityActivity extends BaseActivity {
ActivitySettingsSecurityBinding.inflate(getLayoutInflater()); ActivitySettingsSecurityBinding.inflate(getLayoutInflater());
setContentView(activitySettingsSecurityBinding.getRoot()); setContentView(activitySettingsSecurityBinding.getRoot());
ImageView closeActivity = activitySettingsSecurityBinding.close; activitySettingsSecurityBinding.topAppBar.setNavigationOnClickListener(v -> finish());
initCloseListener();
closeActivity.setOnClickListener(onClickListener);
TextView cacheSizeDataSelected =
activitySettingsSecurityBinding.cacheSizeDataSelected; // setter for data cache size
TextView cacheSizeImagesSelected =
activitySettingsSecurityBinding
.cacheSizeImagesSelected; // setter for images cache size
TextView clearCacheSelected =
activitySettingsSecurityBinding.clearCacheSelected; // setter for clear cache
LinearLayout certsFrame = activitySettingsSecurityBinding.certsFrame;
LinearLayout cacheSizeDataFrame =
activitySettingsSecurityBinding.cacheSizeDataSelectionFrame;
LinearLayout cacheSizeImagesFrame =
activitySettingsSecurityBinding.cacheSizeImagesSelectionFrame;
LinearLayout clearCacheFrame = activitySettingsSecurityBinding.clearCacheSelectionFrame;
cacheSizeDataList = getResources().getStringArray(R.array.cacheSizeList); cacheSizeDataList = getResources().getStringArray(R.array.cacheSizeList);
cacheSizeImagesList = getResources().getStringArray(R.array.cacheSizeList); cacheSizeImagesList = getResources().getStringArray(R.array.cacheSizeList);
cacheSizeDataSelected.setText( activitySettingsSecurityBinding.cacheSizeDataSelected.setText(
tinyDB.getString( tinyDB.getString(
"cacheSizeStr", getString(R.string.cacheSizeDataSelectionSelectedText))); "cacheSizeStr", getString(R.string.cacheSizeDataSelectionSelectedText)));
cacheSizeImagesSelected.setText( activitySettingsSecurityBinding.cacheSizeImagesSelected.setText(
tinyDB.getString( tinyDB.getString(
"cacheSizeImagesStr", "cacheSizeImagesStr",
getString(R.string.cacheSizeImagesSelectionSelectedText))); getString(R.string.cacheSizeImagesSelectionSelectedText)));
@ -101,9 +77,10 @@ public class SettingsSecurityActivity extends BaseActivity {
BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) { BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
case BiometricManager.BIOMETRIC_SUCCESS: case BiometricManager.BIOMETRIC_SUCCESS:
tinyDB.putBoolean("biometricStatus", true); tinyDB.putBoolean("biometricStatus", true);
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources().getString(R.string.settingsSave)); findViewById(android.R.id.content),
getString(R.string.settingsSave));
break; break;
case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE: case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
@ -112,38 +89,45 @@ public class SettingsSecurityActivity extends BaseActivity {
tinyDB.putBoolean("biometricStatus", false); tinyDB.putBoolean("biometricStatus", false);
activitySettingsSecurityBinding.switchBiometric.setChecked( activitySettingsSecurityBinding.switchBiometric.setChecked(
false); false);
Toasty.error( SnackBar.error(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.biometricNotSupported)); getString(R.string.biometricNotSupported));
break; break;
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE: case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
tinyDB.putBoolean("biometricStatus", false); tinyDB.putBoolean("biometricStatus", false);
activitySettingsSecurityBinding.switchBiometric.setChecked( activitySettingsSecurityBinding.switchBiometric.setChecked(
false); false);
Toasty.error( SnackBar.error(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.biometricNotAvailable)); getString(R.string.biometricNotAvailable));
break; break;
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED: case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
tinyDB.putBoolean("biometricStatus", false); tinyDB.putBoolean("biometricStatus", false);
activitySettingsSecurityBinding.switchBiometric.setChecked( activitySettingsSecurityBinding.switchBiometric.setChecked(
false); false);
Toasty.info( SnackBar.info(
appCtx, ctx,
getResources().getString(R.string.enrollBiometric)); findViewById(android.R.id.content),
getString(R.string.enrollBiometric));
break; break;
} }
} else { } else {
tinyDB.putBoolean("biometricStatus", true); tinyDB.putBoolean("biometricStatus", true);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
} }
} else { } else {
tinyDB.putBoolean("biometricStatus", false); tinyDB.putBoolean("biometricStatus", false);
Toasty.success(appCtx, getResources().getString(R.string.settingsSave)); SnackBar.success(
ctx,
findViewById(android.R.id.content),
getString(R.string.settingsSave));
} }
}); });
@ -154,11 +138,11 @@ public class SettingsSecurityActivity extends BaseActivity {
// clear cache setter // clear cache setter
File cacheDir = appCtx.getCacheDir(); File cacheDir = appCtx.getCacheDir();
clearCacheSelected.setText( activitySettingsSecurityBinding.clearCacheSelected.setText(
FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir))); FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir)));
// clear cache // clear cache
clearCacheFrame.setOnClickListener( activitySettingsSecurityBinding.clearCacheSelectionFrame.setOnClickListener(
v1 -> { v1 -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
@ -180,7 +164,7 @@ public class SettingsSecurityActivity extends BaseActivity {
this.overridePendingTransition(0, 0); this.overridePendingTransition(0, 0);
} catch (IOException e) { } catch (IOException e) {
Log.e("SettingsSecurity", e.toString()); // Log.e("SettingsSecurity", e.toString());
} }
}); });
@ -188,7 +172,7 @@ public class SettingsSecurityActivity extends BaseActivity {
}); });
// cache size images selection dialog // cache size images selection dialog
cacheSizeImagesFrame.setOnClickListener( activitySettingsSecurityBinding.cacheSizeImagesSelectionFrame.setOnClickListener(
view -> { view -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
@ -199,7 +183,8 @@ public class SettingsSecurityActivity extends BaseActivity {
cacheSizeImagesSelectedChoice, cacheSizeImagesSelectedChoice,
(dialogInterfaceTheme, i) -> { (dialogInterfaceTheme, i) -> {
cacheSizeImagesSelectedChoice = i; cacheSizeImagesSelectedChoice = i;
cacheSizeImagesSelected.setText( activitySettingsSecurityBinding
.cacheSizeImagesSelected.setText(
cacheSizeImagesList[i]); cacheSizeImagesList[i]);
tinyDB.putString( tinyDB.putString(
"cacheSizeImagesStr", "cacheSizeImagesStr",
@ -207,17 +192,17 @@ public class SettingsSecurityActivity extends BaseActivity {
tinyDB.putInt("cacheSizeImagesId", i); tinyDB.putInt("cacheSizeImagesId", i);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
// cache size data selection dialog // cache size data selection dialog
cacheSizeDataFrame.setOnClickListener( activitySettingsSecurityBinding.cacheSizeDataSelectionFrame.setOnClickListener(
view -> { view -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
@ -228,23 +213,25 @@ public class SettingsSecurityActivity extends BaseActivity {
cacheSizeDataSelectedChoice, cacheSizeDataSelectedChoice,
(dialogInterfaceTheme, i) -> { (dialogInterfaceTheme, i) -> {
cacheSizeDataSelectedChoice = i; cacheSizeDataSelectedChoice = i;
cacheSizeDataSelected.setText(cacheSizeDataList[i]); activitySettingsSecurityBinding
.cacheSizeDataSelected.setText(
cacheSizeDataList[i]);
tinyDB.putString( tinyDB.putString(
"cacheSizeStr", cacheSizeDataList[i]); "cacheSizeStr", cacheSizeDataList[i]);
tinyDB.putInt("cacheSizeId", i); tinyDB.putInt("cacheSizeId", i);
dialogInterfaceTheme.dismiss(); dialogInterfaceTheme.dismiss();
Toasty.success( SnackBar.success(
appCtx, ctx,
getResources() findViewById(android.R.id.content),
.getString(R.string.settingsSave)); getString(R.string.settingsSave));
}); });
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
// certs deletion // certs deletion
certsFrame.setOnClickListener( activitySettingsSecurityBinding.certsFrame.setOnClickListener(
v1 -> { v1 -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(ctx) new MaterialAlertDialogBuilder(ctx)
@ -271,9 +258,4 @@ public class SettingsSecurityActivity extends BaseActivity {
materialAlertDialogBuilder.create().show(); materialAlertDialogBuilder.create().show();
}); });
} }
private void initCloseListener() {
onClickListener = view -> finish();
}
} }

View File

@ -0,0 +1,125 @@
package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.mian.gitnex.R;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.attachments.AttachmentsModel;
/**
* @author M M Arif
*/
public class AttachmentsAdapter extends RecyclerView.Adapter<AttachmentsAdapter.ViewHolder> {
private static AttachmentsReceiverListener AttachmentsReceiveListener;
private List<AttachmentsModel> attachmentsList;
private final Context ctx;
public AttachmentsAdapter(List<AttachmentsModel> attachmentsList, Context ctx) {
this.attachmentsList = attachmentsList;
this.ctx = ctx;
}
@Override
public int getItemCount() {
return attachmentsList == null ? 0 : attachmentsList.size();
}
@NonNull @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_attachments, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
AttachmentsModel currentItem = attachmentsList.get(position);
holder.attachmentsModel = currentItem;
holder.filename.setText(currentItem.getFileName());
if (Arrays.asList("bmp", "gif", "jpg", "jpeg", "png", "webp", "heic", "heif")
.contains(FilenameUtils.getExtension(currentItem.getFileName()).toLowerCase())) {
holder.attachmentViewFrame.setVisibility(View.VISIBLE);
PicassoService.getInstance(ctx)
.get()
.load(currentItem.getUri())
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop()
.error(R.drawable.ic_close)
.into(holder.attachment);
} else {
holder.attachmentViewFrame.setVisibility(View.GONE);
}
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView filename;
public ImageView delete;
public MaterialCardView attachmentViewFrame;
public ImageView attachment;
private AttachmentsModel attachmentsModel;
public ViewHolder(View itemView) {
super(itemView);
filename = itemView.findViewById(R.id.filename);
delete = itemView.findViewById(R.id.delete_attachment);
attachmentViewFrame = itemView.findViewById(R.id.attachmentViewFrame);
attachment = itemView.findViewById(R.id.attachment);
delete.setOnClickListener(
itemDelete -> {
AttachmentsReceiveListener.setAttachmentsData(attachmentsModel.getUri());
deleteAttachment(getBindingAdapterPosition());
notifyDataChanged();
});
}
}
@SuppressLint("NotifyDataSetChanged")
public void notifyDataChanged() {
notifyDataSetChanged();
}
public void updateList(List<AttachmentsModel> list) {
attachmentsList = list;
notifyDataChanged();
}
private void deleteAttachment(int position) {
attachmentsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, attachmentsList.size());
}
public interface AttachmentsReceiverListener {
void setAttachmentsData(Uri myData);
}
public static void setAttachmentsReceiveListener(
AttachmentsReceiverListener attachmentsListener) {
AttachmentsReceiveListener = attachmentsListener;
}
}

View File

@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.card.MaterialCardView;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -72,7 +73,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
loadMoreListener.onLoadMore(); loadMoreListener.onLoadMore();
} }
((DashboardAdapter.DashboardHolder) holder).bindData(activityList.get(position)); ((DashboardAdapter.DashboardHolder) holder).bindData(activityList.get(position), position);
} }
@Override @Override
@ -123,6 +124,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
private final ImageView typeIcon; private final ImageView typeIcon;
private final TextView dashText; private final TextView dashText;
private final LinearLayout dashTextFrame; private final LinearLayout dashTextFrame;
private LinearLayout dashboardLayoutCardsFrame;
private MaterialCardView cardLayout;
private Activity activityObject; private Activity activityObject;
@ -135,6 +138,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
createdTime = itemView.findViewById(R.id.created_time); createdTime = itemView.findViewById(R.id.created_time);
dashText = itemView.findViewById(R.id.text); dashText = itemView.findViewById(R.id.text);
dashTextFrame = itemView.findViewById(R.id.dash_text_frame); dashTextFrame = itemView.findViewById(R.id.dash_text_frame);
dashboardLayoutCardsFrame = itemView.findViewById(R.id.dashboardLayoutCardsFrame);
cardLayout = itemView.findViewById(R.id.cardLayout);
new Handler() new Handler()
.postDelayed( .postDelayed(
@ -353,7 +358,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
200); 200);
} }
void bindData(Activity activity) { void bindData(Activity activity, int position) {
this.activityObject = activity; this.activityObject = activity;
Locale locale = context.getResources().getConfiguration().locale; Locale locale = context.getResources().getConfiguration().locale;
@ -391,7 +396,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ "'>" + "'>"
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "created repository"; typeString = context.getString(R.string.createdRepository);
typeIcon.setImageResource(R.drawable.ic_repo); typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("rename_repo")) { } else if (activity.getOpType().equalsIgnoreCase("rename_repo")) {
@ -402,7 +407,10 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ "'>" + "'>"
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "renamed repository from " + activity.getContent() + " to"; typeString =
String.format(
context.getString(R.string.renamedRepository),
activity.getContent());
typeIcon.setImageResource(R.drawable.ic_repo); typeIcon.setImageResource(R.drawable.ic_repo);
} else if (activity.getOpType().equalsIgnoreCase("star_repo")) { } else if (activity.getOpType().equalsIgnoreCase("star_repo")) {
@ -413,7 +421,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ "'>" + "'>"
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "starred"; typeString = context.getString(R.string.starredRepository);
typeIcon.setImageResource(R.drawable.ic_star); typeIcon.setImageResource(R.drawable.ic_star);
} else if (activity.getOpType().equalsIgnoreCase("transfer_repo")) { } else if (activity.getOpType().equalsIgnoreCase("transfer_repo")) {
@ -424,7 +432,10 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ "'>" + "'>"
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "transferred repository " + activity.getContent() + " to"; typeString =
String.format(
context.getString(R.string.transferredRepository),
activity.getContent());
typeIcon.setImageResource(R.drawable.ic_arrow_up); typeIcon.setImageResource(R.drawable.ic_arrow_up);
} else if (activity.getOpType().equalsIgnoreCase("commit_repo")) { } else if (activity.getOpType().equalsIgnoreCase("commit_repo")) {
@ -447,7 +458,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
activity.getRefName().lastIndexOf("/") + 1) activity.getRefName().lastIndexOf("/") + 1)
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "created branch " + branch + " in"; typeString =
String.format(context.getString(R.string.createdBranch), branch);
} else { } else {
String branch = String branch =
"<font color='" "<font color='"
@ -459,7 +471,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
activity.getRefName().lastIndexOf("/") + 1) activity.getRefName().lastIndexOf("/") + 1)
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "pushed to " + branch + " at"; typeString = String.format(context.getString(R.string.pushedTo), branch);
JSONObject commitsObj = null; JSONObject commitsObj = null;
try { try {
@ -567,7 +579,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "opened issue"; typeString = context.getString(R.string.openedIssue);
typeIcon.setImageResource(R.drawable.ic_issue); typeIcon.setImageResource(R.drawable.ic_issue);
} else if (activity.getOpType().equalsIgnoreCase("comment_issue")) { } else if (activity.getOpType().equalsIgnoreCase("comment_issue")) {
@ -580,7 +592,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "commented on issue"; typeString = context.getString(R.string.commentedOnIssue);
typeIcon.setImageResource(R.drawable.ic_comment); typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("close_issue")) { } else if (activity.getOpType().equalsIgnoreCase("close_issue")) {
@ -593,7 +605,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "closed issue"; typeString = context.getString(R.string.closedIssue);
typeIcon.setImageResource(R.drawable.ic_issue_closed); typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_issue")) { } else if (activity.getOpType().equalsIgnoreCase("reopen_issue")) {
@ -606,7 +618,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "reopened issue"; typeString = context.getString(R.string.reopenedIssue);
typeIcon.setImageResource(R.drawable.ic_reopen); typeIcon.setImageResource(R.drawable.ic_reopen);
} }
} else if (activity.getOpType().contains("pull")) { } else if (activity.getOpType().contains("pull")) {
@ -634,7 +646,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "created pull request"; typeString = context.getString(R.string.createdPR);
typeIcon.setImageResource(R.drawable.ic_pull_request); typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("close_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("close_pull_request")) {
@ -647,7 +659,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "closed pull request"; typeString = context.getString(R.string.closedPR);
typeIcon.setImageResource(R.drawable.ic_issue_closed); typeIcon.setImageResource(R.drawable.ic_issue_closed);
} else if (activity.getOpType().equalsIgnoreCase("reopen_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("reopen_pull_request")) {
@ -660,7 +672,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "reopened pull request"; typeString = context.getString(R.string.reopenedPR);
typeIcon.setImageResource(R.drawable.ic_reopen); typeIcon.setImageResource(R.drawable.ic_reopen);
} else if (activity.getOpType().equalsIgnoreCase("merge_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("merge_pull_request")) {
@ -673,7 +685,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "merged pull request"; typeString = context.getString(R.string.mergedPR);
typeIcon.setImageResource(R.drawable.ic_pull_request); typeIcon.setImageResource(R.drawable.ic_pull_request);
} else if (activity.getOpType().equalsIgnoreCase("approve_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("approve_pull_request")) {
@ -686,7 +698,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "approved"; typeString = context.getString(R.string.approved);
typeIcon.setImageResource(R.drawable.ic_done); typeIcon.setImageResource(R.drawable.ic_done);
} else if (activity.getOpType().equalsIgnoreCase("reject_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("reject_pull_request")) {
@ -699,7 +711,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "suggested changes for"; typeString = context.getString(R.string.suggestedChanges);
typeIcon.setImageResource(R.drawable.ic_diff); typeIcon.setImageResource(R.drawable.ic_diff);
} else if (activity.getOpType().equalsIgnoreCase("comment_pull")) { } else if (activity.getOpType().equalsIgnoreCase("comment_pull")) {
@ -712,7 +724,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "commented on pull request"; typeString = context.getString(R.string.commentedOnPR);
typeIcon.setImageResource(R.drawable.ic_comment); typeIcon.setImageResource(R.drawable.ic_comment);
} else if (activity.getOpType().equalsIgnoreCase("auto_merge_pull_request")) { } else if (activity.getOpType().equalsIgnoreCase("auto_merge_pull_request")) {
@ -725,7 +737,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ context.getResources().getString(R.string.hash) + context.getResources().getString(R.string.hash)
+ id + id
+ "</font>"; + "</font>";
typeString = "automatically merged pull request"; typeString = context.getString(R.string.autoMergePR);
typeIcon.setImageResource(R.drawable.ic_issue_closed); typeIcon.setImageResource(R.drawable.ic_issue_closed);
} }
} else if (activity.getOpType().contains("branch")) { } else if (activity.getOpType().contains("branch")) {
@ -758,7 +770,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "deleted branch " + branch + " at"; typeString = String.format(context.getString(R.string.deletedBranch), branch);
typeIcon.setImageResource(R.drawable.ic_commit); typeIcon.setImageResource(R.drawable.ic_commit);
} }
} else if (activity.getOpType().contains("tag")) { } else if (activity.getOpType().contains("tag")) {
@ -783,7 +795,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "pushed tag " + branch + " to"; typeString = String.format(context.getString(R.string.pushedTag), branch);
typeIcon.setImageResource(R.drawable.ic_commit); typeIcon.setImageResource(R.drawable.ic_commit);
} else if (activity.getOpType().equalsIgnoreCase("delete_tag")) { } else if (activity.getOpType().equalsIgnoreCase("delete_tag")) {
@ -805,7 +817,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "deleted tag " + branch + " from"; typeString = String.format(context.getString(R.string.deletedTag), branch);
typeIcon.setImageResource(R.drawable.ic_commit); typeIcon.setImageResource(R.drawable.ic_commit);
} }
} else if (activity.getOpType().contains("release")) { } else if (activity.getOpType().contains("release")) {
@ -830,7 +842,7 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
.trim() .trim()
+ "</font>"; + "</font>";
typeString = "released " + branch + " at"; typeString = String.format(context.getString(R.string.releasedBranch), branch);
typeIcon.setImageResource(R.drawable.ic_tag); typeIcon.setImageResource(R.drawable.ic_tag);
} }
} else if (activity.getOpType().contains("mirror")) { } else if (activity.getOpType().contains("mirror")) {
@ -845,7 +857,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "synced commits to " + headerString + " at"; typeString =
String.format(context.getString(R.string.syncedCommits), headerString);
typeIcon.setImageResource(R.drawable.ic_tag); typeIcon.setImageResource(R.drawable.ic_tag);
} else if (activity.getOpType().equalsIgnoreCase("mirror_sync_create")) { } else if (activity.getOpType().equalsIgnoreCase("mirror_sync_create")) {
@ -857,7 +870,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "synced new reference " + headerString + " to"; typeString =
String.format(context.getString(R.string.syncedRefs), headerString);
typeIcon.setImageResource(R.drawable.ic_tag); typeIcon.setImageResource(R.drawable.ic_tag);
} else if (activity.getOpType().equalsIgnoreCase("mirror_sync_delete")) { } else if (activity.getOpType().equalsIgnoreCase("mirror_sync_delete")) {
@ -869,7 +883,9 @@ public class DashboardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
+ activity.getRepo().getFullName() + activity.getRepo().getFullName()
+ "</font>"; + "</font>";
typeString = "synced and deleted reference " + headerString + " at"; typeString =
String.format(
context.getString(R.string.syncedDeletedRefs), headerString);
typeIcon.setImageResource(R.drawable.ic_tag); typeIcon.setImageResource(R.drawable.ic_tag);
} }
} else { } else {

View File

@ -32,11 +32,15 @@ import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.card.MaterialCardView; import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.gitnex.tea4j.v2.models.Attachment;
import org.gitnex.tea4j.v2.models.TimelineComment; import org.gitnex.tea4j.v2.models.TimelineComment;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -48,6 +52,7 @@ import org.mian.gitnex.activities.IssueDetailActivity;
import org.mian.gitnex.activities.ProfileActivity; import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.CustomImageViewDialogBinding;
import org.mian.gitnex.fragments.BottomSheetReplyFragment; import org.mian.gitnex.fragments.BottomSheetReplyFragment;
import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.IssuesFragment;
import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.AlertDialogs;
@ -257,6 +262,15 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<RecyclerView.View
timelineDividerView = view.findViewById(R.id.timeline_divider_view); timelineDividerView = view.findViewById(R.id.timeline_divider_view);
timelineLine2 = view.findViewById(R.id.timeline_line_2); timelineLine2 = view.findViewById(R.id.timeline_line_2);
String token = ((BaseActivity) context).getAccount().getAccount().getToken();
new Handler()
.postDelayed(
() -> {
getAttachments(issueComment.getId(), view, token);
},
250);
menu.setOnClickListener( menu.setOnClickListener(
v -> { v -> {
final String loginUid = final String loginUid =
@ -888,20 +902,42 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<RecyclerView.View
} }
if (issueComment.getType().equalsIgnoreCase("review")) { if (issueComment.getType().equalsIgnoreCase("review")) {
timelineView.setVisibility(View.GONE); if (!issueComment.getBody().equalsIgnoreCase("")) {
timelineDividerView.setVisibility(View.GONE);
start.setText(
context.getString(
R.string.timelineReviewLeftComment,
issueComment.getUser().getLogin(),
issueComment.getBody(),
info));
timelineIcon.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_comment));
} else {
timelineView.setVisibility(View.GONE);
timelineDividerView.setVisibility(View.GONE);
}
} else if (issueComment.getType().equalsIgnoreCase("dismiss_review")) { } else if (issueComment.getType().equalsIgnoreCase("dismiss_review")) {
timelineView.setVisibility(View.GONE); timelineView.setVisibility(View.GONE);
timelineDividerView.setVisibility(View.GONE); timelineDividerView.setVisibility(View.GONE);
} else if (issueComment.getType().equalsIgnoreCase("review_request")) { } else if (issueComment.getType().equalsIgnoreCase("review_request")) {
String reviewer;
if (issueComment.getAssignee() != null) {
reviewer = issueComment.getAssignee().getLogin();
} else {
if (issueComment.getAssigneeTeam() != null) {
reviewer = issueComment.getAssigneeTeam().getName();
} else {
reviewer = "";
}
}
start.setText( start.setText(
context.getString( context.getString(
R.string.timelineReviewRequest, R.string.timelineReviewRequest,
issueComment.getUser().getLogin(), issueComment.getUser().getLogin(),
issueComment.getAssignee().getLogin(), reviewer,
info)); info));
timelineIcon.setImageDrawable( timelineIcon.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_unwatch)); ContextCompat.getDrawable(context, R.drawable.ic_watchers));
} }
start.setTextSize(fontSize); start.setTextSize(fontSize);
@ -1286,4 +1322,133 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<RecyclerView.View
} }
} }
} }
private void getAttachments(Long issueIndex, View view, String token) {
LinearLayout attachmentFrame = view.findViewById(R.id.attachmentFrame);
LinearLayout attachmentsView = view.findViewById(R.id.attachmentsView);
Call<List<Attachment>> call =
RetrofitClient.getApiInterface(context)
.issueListIssueCommentAttachments(
issue.getRepository().getOwner(),
issue.getRepository().getName(),
issueIndex);
call.enqueue(
new Callback<>() {
@Override
public void onResponse(
@NonNull Call<List<Attachment>> call,
@NonNull retrofit2.Response<List<Attachment>> response) {
List<Attachment> attachment = response.body();
if (response.code() == 200) {
assert attachment != null;
if (attachment.size() > 0) {
attachmentFrame.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams paramsAttachment =
new LinearLayout.LayoutParams(96, 96);
paramsAttachment.setMargins(0, 0, 48, 0);
for (int i = 0; i < attachment.size(); i++) {
ImageView attachmentView = new ImageView(context);
MaterialCardView materialCardView =
new MaterialCardView(context);
materialCardView.setLayoutParams(paramsAttachment);
materialCardView.setStrokeWidth(0);
materialCardView.setCardBackgroundColor(Color.TRANSPARENT);
if (Arrays.asList(
"bmp", "gif", "jpg", "jpeg", "png", "webp",
"heic", "heif")
.contains(
FilenameUtils.getExtension(
attachment.get(i).getName())
.toLowerCase())) {
PicassoService.getInstance(context)
.get()
.load(
attachment.get(i).getBrowserDownloadUrl()
+ "?token="
+ token)
.placeholder(R.drawable.loader_animated)
.resize(120, 120)
.centerCrop()
.error(R.drawable.ic_close)
.into(attachmentView);
attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI1 = i;
materialCardView.setOnClickListener(
v1 ->
imageViewDialog(
attachment
.get(finalI1)
.getBrowserDownloadUrl(),
token));
} else {
attachmentView.setImageResource(
R.drawable.ic_file_download);
attachmentView.setPadding(4, 4, 4, 4);
attachmentsView.addView(materialCardView);
attachmentView.setLayoutParams(paramsAttachment);
materialCardView.addView(attachmentView);
int finalI = i;
materialCardView.setOnClickListener(
v1 -> {
// filesize = attachment.get(finalI).getSize();
// filename = attachment.get(finalI).getName();
// filehash = attachment.get(finalI).getUuid();
// requestFileDownload();
});
}
}
} else {
attachmentFrame.setVisibility(View.GONE);
}
}
}
@Override
public void onFailure(
@NonNull Call<List<Attachment>> call, @NonNull Throwable t) {}
});
}
private void imageViewDialog(String url, String token) {
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(
context, R.style.ThemeOverlay_Material3_Dialog_Alert);
CustomImageViewDialogBinding imageViewDialogBinding =
CustomImageViewDialogBinding.inflate(LayoutInflater.from(context));
View view = imageViewDialogBinding.getRoot();
materialAlertDialogBuilder.setView(view);
materialAlertDialogBuilder.setNeutralButton(context.getString(R.string.close), null);
PicassoService.getInstance(context)
.get()
.load(url + "?token=" + token)
.placeholder(R.drawable.loader_animated)
.resize(0, 1600)
.onlyScaleDown()
.centerCrop()
.error(R.drawable.ic_close)
.into(imageViewDialogBinding.imageView);
materialAlertDialogBuilder.create().show();
}
} }

View File

@ -8,6 +8,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -41,7 +42,6 @@ public class MostVisitedReposAdapter
private final TextView repoName; private final TextView repoName;
private final TextView orgName; private final TextView orgName;
private final TextView mostVisited; private final TextView mostVisited;
private final ImageView resetCounter;
private MostVisitedViewHolder(View itemView) { private MostVisitedViewHolder(View itemView) {
@ -51,7 +51,7 @@ public class MostVisitedReposAdapter
repoName = itemView.findViewById(R.id.repo_name); repoName = itemView.findViewById(R.id.repo_name);
orgName = itemView.findViewById(R.id.org_name); orgName = itemView.findViewById(R.id.org_name);
mostVisited = itemView.findViewById(R.id.most_visited); mostVisited = itemView.findViewById(R.id.most_visited);
resetCounter = itemView.findViewById(R.id.reset_counter); LinearLayout repoInfoEndFrame = itemView.findViewById(R.id.repo_info_end_frame);
itemView.setOnClickListener( itemView.setOnClickListener(
v -> { v -> {
@ -66,7 +66,7 @@ public class MostVisitedReposAdapter
context.startActivity(intent); context.startActivity(intent);
}); });
resetCounter.setOnClickListener( repoInfoEndFrame.setOnClickListener(
itemDelete -> { itemDelete -> {
MaterialAlertDialogBuilder materialAlertDialogBuilder = MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder( new MaterialAlertDialogBuilder(

View File

@ -161,6 +161,15 @@ public class RetrofitClient {
((BaseActivity) context).getAccount().getCacheDir(context)); ((BaseActivity) context).getAccount().getCacheDir(context));
} }
public static WebApi getWebInterface(Context context, String url) {
return getWebInterface(
context,
url,
((BaseActivity) context).getAccount().getAuthorization(),
((BaseActivity) context).getAccount().getCacheDir(context));
}
public static ApiInterface getApiInterface( public static ApiInterface getApiInterface(
Context context, String url, String token, File cacheFile) { Context context, String url, String token, File cacheFile) {

View File

@ -30,7 +30,7 @@ import org.mian.gitnex.databinding.FragmentNotificationsBinding;
import org.mian.gitnex.helpers.AppUtil; import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.SimpleCallback; import org.mian.gitnex.helpers.SimpleCallback;
import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.contexts.IssueContext; import org.mian.gitnex.helpers.contexts.IssueContext;
import org.mian.gitnex.helpers.contexts.RepositoryContext; import org.mian.gitnex.helpers.contexts.RepositoryContext;
@ -53,6 +53,7 @@ public class NotificationsFragment extends Fragment
private int pageCurrentIndex = 1; private int pageCurrentIndex = 1;
private int pageResultLimit; private int pageResultLimit;
private String currentFilterMode = "unread"; private String currentFilterMode = "unread";
public static String emptyErrorResponse;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
@ -119,21 +120,51 @@ public class NotificationsFragment extends Fragment
(call, voidResponse) -> { (call, voidResponse) -> {
if (voidResponse.isPresent() if (voidResponse.isPresent()
&& voidResponse.get().isSuccessful()) { && voidResponse.get().isSuccessful()) {
Toasty.success( SnackBar.success(
context, context,
requireActivity()
.findViewById(
android.R.id
.content),
getString( getString(
R.string R.string
.markedNotificationsAsRead)); .markedNotificationsAsRead));
pageCurrentIndex = 1; pageCurrentIndex = 1;
loadNotifications(false); loadNotifications(false);
} else { } else {
activity.runOnUiThread(
() -> if (!emptyErrorResponse.isEmpty()) {
Toasty.error( if (emptyErrorResponse.contains(
context, "205")) {
getString(
R.string SnackBar.success(
.genericError))); context,
requireActivity()
.findViewById(
android.R.id
.content),
getString(
R.string
.markedNotificationsAsRead));
pageCurrentIndex = 1;
loadNotifications(false);
}
} else {
activity.runOnUiThread(
() ->
SnackBar.error(
context,
requireActivity()
.findViewById(
android
.R
.id
.content),
getString(
R.string
.genericError)));
}
} }
})); }));

View File

@ -101,18 +101,18 @@ public class RepoInfoFragment extends Fragment {
binding.fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView()); binding.fileContentsFrameHeader.setOnClickListener(v1 -> toggleExpandView());
binding.repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta()); binding.repoMetaFrameHeader.setOnClickListener(v12 -> toggleExpandViewMeta());
binding.repoMetaStarsFrame.setOnClickListener( binding.repoMetaStars.setOnClickListener(
metaStars -> metaStars ->
ctx.startActivity(repository.getIntent(ctx, RepoStargazersActivity.class))); ctx.startActivity(repository.getIntent(ctx, RepoStargazersActivity.class)));
binding.repoMetaWatchersFrame.setOnClickListener( binding.repoMetaWatchers.setOnClickListener(
metaWatchers -> metaWatchers ->
ctx.startActivity(repository.getIntent(ctx, RepoWatchersActivity.class))); ctx.startActivity(repository.getIntent(ctx, RepoWatchersActivity.class)));
binding.repoMetaForksFrame.setOnClickListener( binding.repoMetaForks.setOnClickListener(
metaForks -> ctx.startActivity(repository.getIntent(ctx, RepoForksActivity.class))); metaForks -> ctx.startActivity(repository.getIntent(ctx, RepoForksActivity.class)));
binding.repoMetaPullRequestsFrame.setOnClickListener( binding.repoMetaPullRequests.setOnClickListener(
metaPR -> ((RepoDetailActivity) requireActivity()).viewPager.setCurrentItem(3)); metaPR -> ((RepoDetailActivity) requireActivity()).viewPager.setCurrentItem(3));
setLanguageStatistics(); setLanguageStatistics();
@ -405,7 +405,7 @@ public class RepoInfoFragment extends Fragment {
if (repoInfo.getOpenPrCounter() != null) { if (repoInfo.getOpenPrCounter() != null) {
binding.repoMetaPullRequests.setText(String.valueOf(repoInfo.getOpenPrCounter())); binding.repoMetaPullRequests.setText(String.valueOf(repoInfo.getOpenPrCounter()));
} else { } else {
binding.repoMetaPullRequestsFrame.setVisibility(View.GONE); binding.repoMetaPullRequests.setVisibility(View.GONE);
} }
binding.repoMetaForks.setText(String.valueOf(repoInfo.getForksCount())); binding.repoMetaForks.setText(String.valueOf(repoInfo.getForksCount()));

View File

@ -13,6 +13,7 @@ import okhttp3.ResponseBody;
import org.gitnex.tea4j.v2.models.Repository; import org.gitnex.tea4j.v2.models.Repository;
import org.gitnex.tea4j.v2.models.User; import org.gitnex.tea4j.v2.models.User;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.databinding.FragmentProfileDetailBinding; import org.mian.gitnex.databinding.FragmentProfileDetailBinding;
@ -69,6 +70,16 @@ public class DetailFragment extends Fragment {
getProfileDetail(username); getProfileDetail(username);
getProfileRepository(username); getProfileRepository(username);
binding.userFollowersCount.setOnClickListener(
metaFollowersFrame ->
((ProfileActivity) requireActivity()).viewPager.setCurrentItem(4));
binding.userFollowingCount.setOnClickListener(
metaFollowingFrame ->
((ProfileActivity) requireActivity()).viewPager.setCurrentItem(5));
binding.userStarredReposCount.setOnClickListener(
metaStarredReposFrame ->
((ProfileActivity) requireActivity()).viewPager.setCurrentItem(2));
return binding.getRoot(); return binding.getRoot();
} }
@ -106,11 +117,22 @@ public class DetailFragment extends Fragment {
binding.userEmail.setText(email); binding.userEmail.setText(email);
binding.userFollowersCount.setText( binding.userFollowersCount.setText(
String.valueOf(response.body().getFollowersCount())); String.valueOf(
response.body().getFollowersCount()
+ " "
+ getString(
R.string.profileTabFollowers)));
binding.userFollowingCount.setText( binding.userFollowingCount.setText(
String.valueOf(response.body().getFollowingCount())); String.valueOf(
response.body().getFollowingCount()
+ " "
+ getString(
R.string.profileTabFollowing)));
binding.userStarredReposCount.setText( binding.userStarredReposCount.setText(
String.valueOf(response.body().getStarredReposCount())); String.valueOf(
response.body().getStarredReposCount()
+ " "
+ getString(R.string.starredRepos)));
String[] userLanguageCodes = String[] userLanguageCodes =
response.body().getLanguage().split("-"); response.body().getLanguage().split("-");

View File

@ -297,6 +297,10 @@ public class AppUtil {
return str.matches("^[\\w .-]+$"); return str.matches("^[\\w .-]+$");
} }
public static Boolean checkLabel(String str) { // [a-zA-Z0-9-_. /:]
return str.matches("^[\\w .-/:]+$");
}
public static Boolean checkStringsWithAlphaNumericDashDotUnderscore( public static Boolean checkStringsWithAlphaNumericDashDotUnderscore(
String str) { // [a-zA-Z0-9-_] String str) { // [a-zA-Z0-9-_]
return str.matches("^[\\w.-]+$"); return str.matches("^[\\w.-]+$");

View File

@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.text.Spanned; import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
@ -216,6 +217,9 @@ public class Markdown {
} }
} }
textView.setTypeface(tf); textView.setTypeface(tf);
textView.setTextIsSelectable(true);
textView.setMovementMethod(
LinkMovementMethod.getInstance());
super.beforeSetText(textView, markdown); super.beforeSetText(textView, markdown);
} }
@ -382,6 +386,9 @@ public class Markdown {
} }
} }
textView.setTypeface(tf); textView.setTypeface(tf);
textView.setTextIsSelectable(true);
textView.setMovementMethod(
LinkMovementMethod.getInstance());
super.beforeSetText(textView, markdown); super.beforeSetText(textView, markdown);
} }

View File

@ -1,10 +1,8 @@
package org.mian.gitnex.helpers; package org.mian.gitnex.helpers;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import java.io.File;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import org.mian.gitnex.fragments.NotificationsFragment;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
@ -22,10 +20,6 @@ public interface SimpleCallback<T> extends Callback<T> {
default void onFailure(@NonNull Call<T> call, @NonNull Throwable throwable) { default void onFailure(@NonNull Call<T> call, @NonNull Throwable throwable) {
onFinished(call, Optional.empty()); onFinished(call, Optional.empty());
NotificationsFragment.emptyErrorResponse = throwable.getMessage();
Log.e(
call.request().url().pathSegments().stream()
.collect(Collectors.joining(File.pathSeparator)),
throwable.toString());
} }
} }

View File

@ -15,6 +15,7 @@ public class SnackBar {
Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView(); View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text); TextView textView = sbView.findViewById(R.id.snackbar_text);
snackBar.setBackgroundTint(context.getColor(R.color.material_dynamic_neutral10));
textView.setTextColor(context.getColor(R.color.colorWhite)); textView.setTextColor(context.getColor(R.color.colorWhite));
snackBar.show(); snackBar.show();
} }
@ -23,7 +24,8 @@ public class SnackBar {
Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView(); View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text); TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getColor(R.color.colorLightGreen)); snackBar.setBackgroundTint(context.getColor(R.color.material_dynamic_neutral10));
textView.setTextColor(context.getColor(R.color.colorWhite));
snackBar.show(); snackBar.show();
} }
@ -31,7 +33,8 @@ public class SnackBar {
Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView(); View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text); TextView textView = sbView.findViewById(R.id.snackbar_text);
textView.setTextColor(context.getColor(R.color.lightYellow)); snackBar.setBackgroundTint(context.getColor(R.color.material_dynamic_neutral10));
textView.setTextColor(context.getColor(R.color.warningColor));
snackBar.show(); snackBar.show();
} }
@ -39,6 +42,7 @@ public class SnackBar {
Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); Snackbar snackBar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
View sbView = snackBar.getView(); View sbView = snackBar.getView();
TextView textView = sbView.findViewById(R.id.snackbar_text); TextView textView = sbView.findViewById(R.id.snackbar_text);
snackBar.setBackgroundTint(context.getColor(R.color.material_dynamic_neutral10));
textView.setTextColor(context.getColor(R.color.darkRed)); textView.setTextColor(context.getColor(R.color.darkRed));
snackBar.show(); snackBar.show();
} }

View File

@ -0,0 +1,60 @@
package org.mian.gitnex.helpers.attachments;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author M M Arif
*/
public class AttachmentUtils {
public static File getFile(Context ctx, Uri uri) {
File destinationFilename;
try {
destinationFilename =
new File(
ctx.getFilesDir().getPath() + File.separatorChar + queryName(ctx, uri));
} catch (AssertionError e) {
destinationFilename = new File(uri.getPath());
}
try (InputStream ins = ctx.getContentResolver().openInputStream(uri)) {
createFileFromStream(ins, destinationFilename);
} catch (Exception ex) {
ex.printStackTrace();
}
return destinationFilename;
}
public static String queryName(Context ctx, Uri uri) {
Cursor returnCursor = ctx.getContentResolver().query(uri, null, null, null, null);
assert returnCursor != null;
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
String name = returnCursor.getString(nameIndex);
returnCursor.close();
return name;
}
public static void createFileFromStream(InputStream ins, File destination) {
try (OutputStream os = new FileOutputStream(destination)) {
byte[] buffer = new byte[4096];
int length;
while ((length = ins.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,42 @@
package org.mian.gitnex.helpers.attachments;
import android.net.Uri;
/**
* @author M M Arif
*/
public class AttachmentsModel {
private Uri uri;
private String fileName;
private long fileSize;
public AttachmentsModel(String fileName, Uri uri) {
this.fileName = fileName;
this.uri = uri;
}
public Uri getUri() {
return uri;
}
public void setUri(Uri uri) {
this.uri = uri;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
}

View File

@ -3,13 +3,17 @@ package org.mian.gitnex.notifications;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.content.Intent;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.Settings;
import androidx.core.app.NotificationManagerCompat;
import androidx.work.Constraints; import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy; import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType; import androidx.work.NetworkType;
import androidx.work.PeriodicWorkRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager; import androidx.work.WorkManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.mian.gitnex.R; import org.mian.gitnex.R;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
@ -34,16 +38,11 @@ public class Notifications {
public static void createChannels(Context context) { public static void createChannels(Context context) {
TinyDB tinyDB = TinyDB.getInstance(context);
NotificationManager notificationManager = NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Delete old notification channels
notificationManager.deleteNotificationChannel(
context.getPackageName()); // TODO Can be removed in future versions
// Create new notification channels // Create new notification channels
NotificationChannel mainChannel = NotificationChannel mainChannel =
new NotificationChannel( new NotificationChannel(
@ -53,20 +52,6 @@ public class Notifications {
mainChannel.setDescription( mainChannel.setDescription(
context.getString(R.string.mainNotificationChannelDescription)); context.getString(R.string.mainNotificationChannelDescription));
if (tinyDB.getBoolean("notificationsEnableVibration", true)) {
mainChannel.setVibrationPattern(Constants.defaultVibrationPattern);
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 = NotificationChannel downloadChannel =
new NotificationChannel( new NotificationChannel(
Constants.downloadNotificationChannelId, Constants.downloadNotificationChannelId,
@ -89,8 +74,48 @@ public class Notifications {
TinyDB tinyDB = TinyDB.getInstance(context); TinyDB tinyDB = TinyDB.getInstance(context);
int delay;
if (tinyDB.getInt("notificationsPollingDelayId") == 0) {
delay = 15;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 1) {
delay = 30;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 2) {
delay = 45;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 3) {
delay = 60;
} else {
delay = Constants.defaultPollingDelay;
}
if (tinyDB.getBoolean("notificationsEnabled", true)) { if (tinyDB.getBoolean("notificationsEnabled", true)) {
if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.pageTitleNotifications)
.setMessage(context.getString(R.string.openAppSettings))
.setNeutralButton(
R.string.cancelButton, (dialog, which) -> dialog.dismiss())
.setPositiveButton(
R.string.isOpen,
(dialog, which) -> {
Intent intent =
new Intent(
Settings
.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri =
Uri.fromParts(
"package",
context.getPackageName(),
null);
intent.setData(uri);
context.startActivity(intent);
});
materialAlertDialogBuilder.create().show();
return;
}
Constraints.Builder constraints = Constraints.Builder constraints =
new Constraints.Builder() new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) .setRequiredNetworkType(NetworkType.CONNECTED)
@ -98,20 +123,11 @@ public class Notifications {
.setRequiresStorageNotLow(false) .setRequiresStorageNotLow(false)
.setRequiresCharging(false); .setRequiresCharging(false);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { constraints.setRequiresDeviceIdle(false);
constraints.setRequiresDeviceIdle(false);
}
int pollingDelayMinutes =
Math.max(
tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay),
15);
PeriodicWorkRequest periodicWorkRequest = PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder( new PeriodicWorkRequest.Builder(
NotificationsWorker.class, NotificationsWorker.class, delay, TimeUnit.MINUTES)
pollingDelayMinutes,
TimeUnit.MINUTES)
.setConstraints(constraints.build()) .setConstraints(constraints.build())
.addTag(Constants.notificationsWorkerId) .addTag(Constants.notificationsWorkerId)
.build(); .build();
@ -119,7 +135,7 @@ public class Notifications {
WorkManager.getInstance(context) WorkManager.getInstance(context)
.enqueueUniquePeriodicWork( .enqueueUniquePeriodicWork(
Constants.notificationsWorkerId, Constants.notificationsWorkerId,
ExistingPeriodicWorkPolicy.KEEP, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
periodicWorkRequest); periodicWorkRequest);
} }
} }

View File

@ -1,17 +1,23 @@
package org.mian.gitnex.notifications; package org.mian.gitnex.notifications;
import android.Manifest;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.content.pm.PackageManager;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri;
import android.provider.Settings;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.TaskStackBuilder;
import androidx.work.Worker; import androidx.work.Worker;
import androidx.work.WorkerParameters; import androidx.work.WorkerParameters;
import java.util.Date; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.time.ZonedDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -22,7 +28,6 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi; import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi; import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount; import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Constants; import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.TinyDB; import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version; import org.mian.gitnex.helpers.Version;
@ -35,7 +40,6 @@ import retrofit2.Response;
public class NotificationsWorker extends Worker { public class NotificationsWorker extends Worker {
private final Context context; private final Context context;
private final TinyDB tinyDB;
private final Map<UserAccount, Map<String, String>> userAccounts; private final Map<UserAccount, Map<String, String>> userAccounts;
public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
@ -45,9 +49,27 @@ public class NotificationsWorker extends Worker {
UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class); UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class);
this.context = context; this.context = context;
this.tinyDB = TinyDB.getInstance(context); TinyDB tinyDB = TinyDB.getInstance(context);
assert userAccountsApi != null;
this.userAccounts = new HashMap<>(userAccountsApi.getCount()); this.userAccounts = new HashMap<>(userAccountsApi.getCount());
int delay;
if (tinyDB.getInt("notificationsPollingDelayId") == 0) {
delay = 15;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 1) {
delay = 30;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 2) {
delay = 45;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 3) {
delay = 60;
} else {
delay = Constants.defaultPollingDelay;
}
ZonedDateTime zdt = ZonedDateTime.now();
zdt = zdt.minusMinutes(delay);
String previousTimestamp = String.valueOf(zdt.toOffsetDateTime());
for (UserAccount userAccount : userAccountsApi.loggedInUserAccounts()) { for (UserAccount userAccount : userAccountsApi.loggedInUserAccounts()) {
// We do also accept empty values, since the server version was not saved properly in // We do also accept empty values, since the server version was not saved properly in
@ -57,8 +79,7 @@ public class NotificationsWorker extends Worker {
|| new Version(userAccount.getServerVersion()).higherOrEqual("1.12.3")) { || new Version(userAccount.getServerVersion()).higherOrEqual("1.12.3")) {
Map<String, String> userAccountParameters = new HashMap<>(); Map<String, String> userAccountParameters = new HashMap<>();
userAccountParameters.put( userAccountParameters.put("previousTimestamp", previousTimestamp);
"previousTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
userAccounts.put(userAccount, userAccountParameters); userAccounts.put(userAccount, userAccountParameters);
} }
@ -67,56 +88,31 @@ public class NotificationsWorker extends Worker {
@NonNull @Override @NonNull @Override
public Result doWork() { public Result doWork() {
pollingLoops(); startPolling();
return Result.success(); return Result.success();
} }
/** Used to bypass the 15-minute limit of {@code WorkManager}. */
private void pollingLoops() {
int notificationLoops =
tinyDB.getInt("pollingDelayMinutes", Constants.defaultPollingDelay) < 15
? Math.min(
15
- tinyDB.getInt(
"pollingDelayMinutes",
Constants.defaultPollingDelay),
10)
: 1;
for (int i = 0; i < notificationLoops; i++) {
long startPollingTime = System.currentTimeMillis();
startPolling();
try {
if (notificationLoops > 1 && i < (notificationLoops - 1)) {
Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime));
}
} catch (InterruptedException ignored) {
}
}
}
private void startPolling() { private void startPolling() {
for (UserAccount userAccount : userAccounts.keySet()) { for (UserAccount userAccount : userAccounts.keySet()) {
Map<String, String> userAccountParameters = userAccounts.get(userAccount); Map<String, String> userAccountParameters = userAccounts.get(userAccount);
assert userAccountParameters != null;
try { try {
assert userAccountParameters != null;
Call<List<NotificationThread>> call = Call<List<NotificationThread>> call =
RetrofitClient.getApiInterface( RetrofitClient.getApiInterface(
context, context,
userAccount.getInstanceUrl(), userAccount.getInstanceUrl(),
userAccount.getToken(), "token " + userAccount.getToken(),
null) null)
.notifyGetList( .notifyGetList2(
false, false,
List.of("unread"), List.of("unread"),
null, null,
new Date(userAccountParameters.get("previousTimestamp")), userAccountParameters.get("previousTimestamp"),
null, null,
null, 1,
1); 25);
Response<List<NotificationThread>> response = call.execute(); Response<List<NotificationThread>> response = call.execute();
@ -125,8 +121,6 @@ public class NotificationsWorker extends Worker {
if (!notificationThreads.isEmpty()) { if (!notificationThreads.isEmpty()) {
sendNotifications(userAccount, notificationThreads); sendNotifications(userAccount, notificationThreads);
} }
userAccountParameters.put(
"previousTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
} }
} catch (Exception ignored) { } catch (Exception ignored) {
} }
@ -153,10 +147,37 @@ public class NotificationsWorker extends Worker {
.setSmallIcon(R.drawable.gitnex_transparent) .setSmallIcon(R.drawable.gitnex_transparent)
.setGroup(userAccount.getUserName()) .setGroup(userAccount.getUserName())
.setGroupSummary(true) .setGroupSummary(true)
.setAutoCancel(true)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.setAutoCancel(true)
.build(); .build();
if (ActivityCompat.checkSelfPermission(
getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.pageTitleNotifications)
.setMessage(context.getString(R.string.openAppSettings))
.setNeutralButton(
R.string.cancelButton, (dialog, which) -> dialog.dismiss())
.setPositiveButton(
R.string.isOpen,
(dialog, which) -> {
Intent intent =
new Intent(
Settings
.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri =
Uri.fromParts(
"package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
});
materialAlertDialogBuilder.create().show();
return;
}
notificationManagerCompat.notify(userAccount.getAccountId(), summaryNotification); notificationManagerCompat.notify(userAccount.getAccountId(), summaryNotification);
for (NotificationThread notificationThread : notificationThreads) { for (NotificationThread notificationThread : notificationThreads) {
@ -189,25 +210,12 @@ public class NotificationsWorker extends Worker {
private NotificationCompat.Builder getBaseNotificationBuilder() { private NotificationCompat.Builder getBaseNotificationBuilder() {
NotificationCompat.Builder builder = return new NotificationCompat.Builder(context, Constants.mainNotificationChannelId)
new NotificationCompat.Builder(context, Constants.mainNotificationChannelId) .setSmallIcon(R.drawable.gitnex_transparent)
.setSmallIcon(R.drawable.gitnex_transparent) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setCategory(NotificationCompat.CATEGORY_MESSAGE) .setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true);
.setAutoCancel(true);
if (tinyDB.getBoolean("notificationsEnableLights", true)) {
builder.setLights(tinyDB.getInt("notificationsLightColor", Color.GREEN), 1500, 1500);
}
if (tinyDB.getBoolean("notificationsEnableVibration", true)) {
builder.setVibrate(Constants.defaultVibrationPattern);
} else {
builder.setVibrate(null);
}
return builder;
} }
private PendingIntent getPendingIntent(@NonNull UserAccount userAccount) { private PendingIntent getPendingIntent(@NonNull UserAccount userAccount) {
@ -218,7 +226,10 @@ public class NotificationsWorker extends Worker {
intent.putExtra("switchAccountId", userAccount.getAccountId()); intent.putExtra("switchAccountId", userAccount.getAccountId());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
return PendingIntent.getActivity( TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
context, userAccount.getAccountId(), intent, PendingIntent.FLAG_UPDATE_CURRENT); stackBuilder.addNextIntentWithParentStack(intent);
return stackBuilder.getPendingIntent(
1, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
} }
} }

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="m21.44,11.05 l-9.19,9.19a6,6 0,0 1,-8.49 -8.49l8.57,-8.57A4,4 0,1 1,18 8.84l-8.59,8.57a2,2 0,0 1,-2.83 -2.83l8.49,-8.48"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14.5,2H6a2,2 0,0 0,-2 2v16a2,2 0,0 0,2 2h12a2,2 0,0 0,2 -2V7.5L14.5,2z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M14,2l0,6l6,0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="M12,18v-6"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
<path
android:pathData="m9,15 l3,3 3,-3"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="?attr/iconsColor"
android:strokeLineCap="round"/>
</vector>

View File

@ -3,25 +3,25 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24">
<path <path
android:fillColor="#00000000" android:pathData="M5,3L19,3A2,2 0,0 1,21 5L21,19A2,2 0,0 1,19 21L5,21A2,2 0,0 1,3 19L3,5A2,2 0,0 1,5 3z"
android:pathData="M3,12L21,12" android:strokeLineJoin="round"
android:strokeWidth="2" android:strokeWidth="2"
android:strokeColor="?attr/iconsColor" android:fillColor="#00000000"
android:strokeLineCap="round" android:strokeColor="?attr/iconsColor"
android:strokeLineJoin="round"/> android:strokeLineCap="round"/>
<path <path
android:fillColor="#00000000" android:pathData="M9,3v18"
android:pathData="M3,6L21,6" android:strokeLineJoin="round"
android:strokeWidth="2" android:strokeWidth="2"
android:strokeColor="?attr/iconsColor" android:fillColor="#00000000"
android:strokeLineCap="round" android:strokeColor="?attr/iconsColor"
android:strokeLineJoin="round"/> android:strokeLineCap="round"/>
<path <path
android:fillColor="#00000000" android:pathData="m14,9 l3,3 -3,3"
android:pathData="M3,18L21,18" android:strokeLineJoin="round"
android:strokeWidth="2" android:strokeWidth="2"
android:strokeColor="?attr/iconsColor" android:fillColor="#00000000"
android:strokeLineCap="round" android:strokeColor="?attr/iconsColor"
android:strokeLineJoin="round"/> android:strokeLineCap="round"/>
</vector> </vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

View File

@ -3,10 +3,10 @@
android:shape="rectangle"> android:shape="rectangle">
<corners <corners
android:topLeftRadius="@dimen/dimen32dp" android:topLeftRadius="@dimen/dimen28dp"
android:topRightRadius="@dimen/dimen32dp"/> android:topRightRadius="@dimen/dimen28dp"/>
<padding android:top="@dimen/dimen24dp"/> <padding android:top="@dimen/dimen28dp"/>
<solid android:color="?attr/primaryBackgroundColor"/> <solid android:color="?attr/primaryBackgroundColor"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="?attr/primaryBackgroundColor"/> <solid android:color="?attr/materialCardBackgroundColor"/>
<corners android:radius="18dp"/> <corners android:radius="18dp"/>
</shape> </shape>

View File

@ -1,72 +1,62 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor" app:contentScrim="?attr/primaryBackgroundColor"
tools:ignore="UnusedAttribute"> android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleAddEmail"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/save"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleAddEmail"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <LinearLayout
android:id="@+id/userEmailLayout" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_marginTop="@dimen/dimen8dp" android:padding="@dimen/dimen16dp">
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/accountEmailTitle" <com.google.android.material.textfield.TextInputLayout
android:textColorHint="?attr/hintColor" android:id="@+id/userEmailLayout"
app:boxBackgroundColor="?attr/inputBackgroundColor" android:layout_width="match_parent"
app:boxStrokeErrorColor="@color/darkRed" android:layout_height="wrap_content"
app:endIconMode="clear_text" android:layout_marginTop="@dimen/dimen8dp"
app:endIconTint="?attr/iconsColor" android:layout_marginBottom="@dimen/dimen8dp"
app:hintTextColor="?attr/hintColor"> android:hint="@string/accountEmailTitle"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/userEmail" android:id="@+id/userEmail"
@ -79,15 +69,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton </LinearLayout>
android:id="@+id/addEmailButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/saveButton"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -67,7 +67,6 @@
android:id="@+id/addCollaboratorSearchLayout" android:id="@+id/addCollaboratorSearchLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:boxBackgroundColor="?attr/inputBackgroundColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:hintTextColor="?attr/hintColor" app:hintTextColor="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"

View File

@ -1,155 +1,135 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layoutNewAccount"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp" android:fitsSystemWindows="true">
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/addNewAccount"
android:contentDescription="@string/close" app:layout_collapseMode="pin"
android:gravity="center_vertical" app:menu="@menu/add_new_account_menu"
android:src="@drawable/ic_arrow_back"/> app:navigationIcon="@drawable/ic_arrow_back" />
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/dimen20dp"
android:ellipsize="none"
android:scrollbars="horizontal"
android:singleLine="true"
android:text="@string/addNewAccount"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:padding="@dimen/dimen16dp"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputLayout <LinearLayout
android:id="@+id/protocolSpinnerLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp" android:orientation="vertical"
android:layout_marginBottom="@dimen/dimen8dp" android:padding="@dimen/dimen16dp"
android:hint="@string/protocol" app:layout_constraintTop_toTopOf="parent">
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<AutoCompleteTextView <com.google.android.material.textfield.TextInputLayout
android:id="@+id/protocolSpinner" android:id="@+id/protocolSpinnerLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeOptions="actionNext" android:layout_marginTop="@dimen/dimen8dp"
android:inputType="none" android:layout_marginBottom="@dimen/dimen8dp"
android:labelFor="@+id/protocolSpinner" android:hint="@string/protocol"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/instanceUrlLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/instanceUrl"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_link"
app:startIconTint="?attr/iconsColor"
app:helperText="@string/instanceHelperText">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/instanceUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
</com.google.android.material.textfield.TextInputLayout> <AutoCompleteTextView
android:id="@+id/protocolSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="none"
android:labelFor="@+id/protocolSpinner"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp" />
<com.google.android.material.textfield.TextInputLayout </com.google.android.material.textfield.TextInputLayout>
android:id="@+id/loginTokenLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/copyToken"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginToken" android:id="@+id/instanceUrlLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeOptions="actionNext" android:layout_marginTop="@dimen/dimen8dp"
android:singleLine="true" android:layout_marginBottom="@dimen/dimen8dp"
android:textColor="?attr/inputTextColor" android:hint="@string/instanceUrl"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_link"
app:startIconTint="?attr/iconsColor"
app:helperText="@string/instanceHelperText">
</com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputEditText
android:id="@+id/instanceUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
<com.google.android.material.button.MaterialButton </com.google.android.material.textfield.TextInputLayout>
android:id="@+id/addNewAccount"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/addNewAccountText"
android:textColor="?attr/materialCardBackgroundColor"
android:textSize="@dimen/dimen16sp"
android:textStyle="bold"/>
</LinearLayout> <com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginTokenLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/copyToken"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
</LinearLayout> <com.google.android.material.textfield.TextInputEditText
android:id="@+id/loginToken"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,55 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleNewFile"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/file_create_edit_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleNewFile"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newFileNameTintCopy" android:hint="@string/newFileNameTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -95,7 +83,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newFileContentTintCopy" android:hint="@string/newFileContentTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -135,7 +122,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newFileBranches" android:hint="@string/newFileBranches"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:helperText="@string/newFileEmptyBranchMessage" app:helperText="@string/newFileEmptyBranchMessage"
app:helperTextEnabled="true" app:helperTextEnabled="true"
@ -164,7 +150,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newFileMessageTintCopy" android:hint="@string/newFileMessageTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -186,17 +171,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/newFileCreate"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newFileButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,48 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleCreateNewIssue"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close" />
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleCreateNewIssue"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@ -53,18 +42,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:visibility="gone" android:visibility="gone"
app:indicatorColor="?attr/progressIndicatorColor"/> app:indicatorColor="?attr/progressIndicatorColor" />
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueTitleLayout" android:id="@+id/newIssueTitleLayout"
@ -74,7 +63,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueTitle" android:hint="@string/newIssueTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -97,7 +85,7 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueDescriptionLayout" android:id="@+id/newIssueDescriptionLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -105,7 +93,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDescriptionTitle" android:hint="@string/newIssueDescriptionTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -123,9 +110,9 @@
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" /> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/markdown_preview" android:id="@+id/markdown_preview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -137,7 +124,7 @@
android:textSize="@dimen/dimen14sp" android:textSize="@dimen/dimen14sp"
android:visibility="gone" /> android:visibility="gone" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueAssigneesListLayout" android:id="@+id/newIssueAssigneesListLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -145,7 +132,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueAssigneesListTitle" android:hint="@string/newIssueAssigneesListTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
@ -158,9 +144,9 @@
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" /> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueMilestoneSpinnerLayout" android:id="@+id/newIssueMilestoneSpinnerLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu" style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -169,7 +155,7 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueMilestoneTitle" android:hint="@string/newIssueMilestoneTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor" app:boxBackgroundColor="?attr/primaryBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -182,9 +168,9 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp" /> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueLabelsLayout" android:id="@+id/newIssueLabelsLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -192,7 +178,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueLabelsTitle" android:hint="@string/newIssueLabelsTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
@ -205,9 +190,9 @@
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" /> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newIssueDueDateLayout" android:id="@+id/newIssueDueDateLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -215,7 +200,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDueDateTitle" android:hint="@string/newIssueDueDateTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -226,13 +210,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="false" android:focusable="false"
android:maxLines="1"
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" /> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/createNewIssueButton" android:id="@+id/createNewIssueButton"
@ -241,10 +224,11 @@
android:layout_marginTop="@dimen/dimen8dp" android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy" android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor" android:textColor="?attr/materialCardBackgroundColor"
android:visibility="gone"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,125 +1,111 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleCreateLabel"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_label_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleCreateLabel"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/labelNameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/labelName"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/labelName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/dimen32dp" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp" android:orientation="vertical"
android:orientation="horizontal"> android:padding="@dimen/dimen16dp">
<TextView <com.google.android.material.textfield.TextInputLayout
android:id="@+id/labelText" android:id="@+id/labelNameLayout"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_marginTop="@dimen/dimen8dp"
android:layout_weight=".95" android:layout_marginBottom="@dimen/dimen8dp"
android:gravity="center_vertical" android:hint="@string/labelName"
android:text="@string/labelColor" android:textColorHint="?attr/hintColor"
android:textColor="?attr/primaryTextColor" app:boxStrokeErrorColor="@color/darkRed"
android:textSize="@dimen/dimen16sp"/> app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<com.google.android.material.card.MaterialCardView <com.google.android.material.textfield.TextInputEditText
style="?attr/materialCardViewElevatedStyle" android:id="@+id/labelName"
android:layout_width="@dimen/dimen28dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen28dp" android:layout_height="wrap_content"
app:cardCornerRadius="@dimen/dimen16dp" android:textColor="?attr/inputTextColor"
app:cardElevation="@dimen/dimen0dp"> android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dimen32dp"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="horizontal">
<TextView <TextView
android:id="@+id/colorPicker" android:id="@+id/labelText"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/releasePre"/> android:layout_gravity="center_vertical"
android:layout_weight=".95"
android:gravity="center_vertical"
android:text="@string/labelColor"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen48dp"
android:layout_height="@dimen/dimen28dp"
app:cardCornerRadius="@dimen/dimen16dp"
app:cardElevation="@dimen/dimen0dp">
<TextView
android:id="@+id/colorPicker"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/releasePre" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</LinearLayout> </LinearLayout>
<com.google.android.material.button.MaterialButton </androidx.core.widget.NestedScrollView>
android:id="@+id/createLabelButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View File

@ -1,55 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleCreateMilestone"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleCreateMilestone"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newMilestoneTitle" android:hint="@string/newMilestoneTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -93,7 +81,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newMilestoneDescription" android:hint="@string/newMilestoneDescription"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -136,7 +123,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newMilestoneDueDate" android:hint="@string/newMilestoneDueDate"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -155,18 +141,9 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/createNewMilestoneButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/adminCreateNewUser"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/adminCreateNewUser"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/fullNameLayout" android:id="@+id/fullNameLayout"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userFullNameText" android:hint="@string/userFullNameText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -93,7 +81,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userUserName" android:hint="@string/userUserName"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -120,7 +107,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userEmail" android:hint="@string/userEmail"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -147,7 +133,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userPassword" android:hint="@string/userPassword"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -165,17 +150,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/createUserButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleCreateOrganization"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleCreateOrganization"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/newOrganizationNameLayout" android:id="@+id/newOrganizationNameLayout"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newOrgTintCopy" android:hint="@string/newOrgTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -93,7 +81,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newOrgDescTintCopy" android:hint="@string/newOrgDescTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -116,18 +103,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/createNewOrganizationButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,48 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleNewPullRequest"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleNewPullRequest"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@ -53,12 +42,12 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:indeterminate="true" android:indeterminate="true"
android:visibility="gone" android:visibility="gone"
app:indicatorColor="?attr/progressIndicatorColor"/> app:indicatorColor="?attr/progressIndicatorColor" />
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -74,7 +63,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueTitle" android:hint="@string/newIssueTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -105,7 +93,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDescriptionTitle" android:hint="@string/newIssueDescriptionTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -146,7 +133,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/mergeIntoBranch" android:hint="@string/mergeIntoBranch"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -170,7 +156,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/pullFromBranch" android:hint="@string/pullFromBranch"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -194,7 +179,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueMilestoneTitle" android:hint="@string/newIssueMilestoneTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -217,7 +201,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueLabelsTitle" android:hint="@string/newIssueLabelsTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
@ -240,7 +223,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDueDateTitle" android:hint="@string/newIssueDueDateTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -259,17 +241,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/createPr"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +1,51 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/createRelease"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_release_tag_menu"
android:contentDescription="@string/close" app:popupTheme="@style/Widget.Material3.PopupMenu"
android:focusable="true" app:navigationIcon="@drawable/ic_close" />
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/createRelease"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/releaseTitleLayout" android:id="@+id/releaseTitleLayout"
@ -65,7 +55,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/releaseTitleText" android:hint="@string/releaseTitleText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -93,7 +82,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/releaseTagNameText" android:hint="@string/releaseTagNameText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -121,7 +109,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/releaseContentText" android:hint="@string/releaseContentText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -162,7 +149,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/releaseBranchText" android:hint="@string/releaseBranchText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -197,26 +183,8 @@
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/createNewRelease"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/createNewTag"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/create_tag"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,55 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleNewRepo"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleNewRepo"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -66,7 +55,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newRepoOwner" android:hint="@string/newRepoOwner"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -77,7 +65,7 @@
android:inputType="none" android:inputType="none"
android:labelFor="@+id/ownerSpinner" android:labelFor="@+id/ownerSpinner"
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -89,7 +77,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newRepoTintCopy" android:hint="@string/newRepoTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -103,7 +90,56 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/defaultBranchFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/infoTabRepoDefaultBranch"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/defaultBranch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:text="@string/main"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/issueLabelsFrame"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newRepoIssueLabels"
android:textColorHint="?attr/hintColor"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<AutoCompleteTextView
android:id="@+id/issueLabels"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:labelFor="@+id/issueLabels"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -115,7 +151,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newRepoDescTintCopy" android:hint="@string/newRepoDescTintCopy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -133,7 +168,30 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/licenseFrame"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/license"
android:textColorHint="?attr/hintColor"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<AutoCompleteTextView
android:id="@+id/licenses"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:labelFor="@+id/licenses"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -145,21 +203,20 @@
android:checked="true" android:checked="true"
android:text="@string/newRepoPrivateCopy" android:text="@string/newRepoPrivateCopy"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
<com.google.android.material.button.MaterialButton <CheckBox
android:id="@+id/createNewRepoButton" android:id="@+id/setAsTemplate"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp" android:layout_marginTop="@dimen/dimen10dp"
android:text="@string/newCreateButtonCopy" android:checked="false"
android:textColor="?attr/materialCardBackgroundColor" android:text="@string/setAsTemplate"
android:textStyle="bold"/> android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleCreateTeam"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleCreateTeam"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/teamNameLayout" android:id="@+id/teamNameLayout"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newTeamTitle" android:hint="@string/newTeamTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -81,7 +69,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -93,7 +81,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newTeamDesc" android:hint="@string/newTeamDesc"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -111,7 +98,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -123,7 +110,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newTeamPermission" android:hint="@string/newTeamPermission"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -136,7 +122,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -147,7 +133,7 @@
android:gravity="start" android:gravity="start"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen12sp" android:textSize="@dimen/dimen12sp"
android:visibility="gone"/> android:visibility="gone" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/teamAccessControlsLayout" android:id="@+id/teamAccessControlsLayout"
@ -157,7 +143,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newTeamAccessControls" android:hint="@string/newTeamAccessControls"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -170,7 +155,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -178,19 +163,10 @@
android:id="@+id/teamAccessControlsArray" android:id="@+id/teamAccessControlsArray"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="gone"/> android:visibility="gone" />
<com.google.android.material.button.MaterialButton
android:id="@+id/createTeamButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/newCreateButtonCopy"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,61 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/editIssueNavHeader"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/editIssueNavHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/editIssueTitleLayout" android:id="@+id/editIssueTitleLayout"
@ -65,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueTitle" android:hint="@string/newIssueTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -93,7 +81,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDescriptionTitle" android:hint="@string/newIssueDescriptionTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -134,7 +121,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueMilestoneTitle" android:hint="@string/newIssueMilestoneTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -157,7 +143,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueDueDateTitle" android:hint="@string/newIssueDueDateTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -176,17 +161,8 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/editIssueButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/saveButton"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -132,197 +132,231 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor" android:orientation="vertical">
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/dimen12dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical" android:background="?attr/materialCardBackgroundColor"
android:orientation="horizontal"> android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
<com.google.android.material.card.MaterialCardView android:padding="@dimen/dimen12dp">
style="?attr/materialCardViewElevatedStyle"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
app:cardCornerRadius="@dimen/dimen12dp"
app:cardElevation="@dimen/dimen0dp">
<ImageView
android:id="@+id/assigneeAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0"
android:contentDescription="@string/generalImgContentText"
tools:srcCompat="@tools:sample/avatars"
tools:ignore="TooDeepLayout" />
</com.google.android.material.card.MaterialCardView>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginLeft="@dimen/dimen16dp" android:gravity="center_vertical"
android:layout_marginRight="@dimen/dimen16dp" android:orientation="horizontal">
android:layout_weight="1"
android:orientation="vertical">
<TextView <com.google.android.material.card.MaterialCardView
android:id="@+id/author" style="?attr/materialCardViewElevatedStyle"
android:layout_width="wrap_content" android:layout_width="@dimen/dimen24dp"
android:layout_height="wrap_content" android:layout_height="@dimen/dimen24dp"
android:ellipsize="middle" app:cardCornerRadius="@dimen/dimen12dp"
android:singleLine="true" app:cardElevation="@dimen/dimen0dp">
android:textColor="?attr/primaryTextColor"
android:textSize="14sp" <ImageView
android:textStyle="bold" /> android:id="@+id/assigneeAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0"
android:contentDescription="@string/generalImgContentText"
tools:srcCompat="@tools:sample/avatars"
tools:ignore="TooDeepLayout" />
</com.google.android.material.card.MaterialCardView>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_marginLeft="@dimen/dimen16dp"
android:layout_marginRight="@dimen/dimen16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView <TextView
android:id="@+id/issueCreatedTime" android:id="@+id/author"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:ellipsize="middle"
android:textColor="?attr/hintColor" android:singleLine="true"
android:textSize="12sp" android:textIsSelectable="true"
android:visibility="gone" /> android:textColor="?attr/primaryTextColor"
android:textSize="14sp"
android:textStyle="bold" />
<TextView <LinearLayout
android:id="@+id/issueModified" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:orientation="horizontal">
android:text="@string/modifiedText"
android:textColor="?attr/hintColor" <TextView
android:textSize="12sp" android:id="@+id/issueCreatedTime"
android:visibility="gone" /> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
<TextView
android:id="@+id/issueModified"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="@string/modifiedText"
android:textColor="?attr/hintColor"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> <LinearLayout
android:id="@+id/dueDateFrame"
<LinearLayout android:layout_width="match_parent"
android:id="@+id/dueDateFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText" android:gravity="end|center_vertical"
app:srcCompat="@drawable/ic_calendar" /> android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<TextView <ImageView
android:id="@+id/issueDueDate" android:layout_width="@dimen/dimen20dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:contentDescription="@string/generalImgContentText"
android:layout_marginStart="@dimen/dimen8dp" app:srcCompat="@drawable/ic_calendar" />
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout> <TextView
android:id="@+id/issueDueDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textIsSelectable="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
<LinearLayout </LinearLayout>
android:id="@+id/milestoneFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_milestone" />
<TextView
android:id="@+id/issueMilestone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout>
<HorizontalScrollView
android:id="@+id/assigneesScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout <LinearLayout
android:id="@+id/frameAssignees" android:id="@+id/milestoneFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|center_vertical"
android:orientation="horizontal"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="@dimen/dimen20dp"
android:layout_height="wrap_content"
android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_milestone" />
<TextView
android:id="@+id/issueMilestone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen8dp"
android:singleLine="true"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout>
<HorizontalScrollView
android:id="@+id/assigneesScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameAssignees"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="@dimen/dimen10dp"
android:gravity="end"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/issueDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen8dp"
android:autoLink="web"
android:gravity="start"
android:visibility="gone"
android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue"
android:textIsSelectable="true"
android:textSize="@dimen/dimen14sp" />
<HorizontalScrollView
android:id="@+id/labelsScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameLabels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/commentReactionBadges"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="@dimen/dimen10dp" android:layout_marginTop="@dimen/dimen10dp"
android:gravity="end" android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/attachmentFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
android:orientation="vertical">
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen4dp" />
<LinearLayout
android:id="@+id/attachmentsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dimen12dp"
android:orientation="horizontal"> android:orientation="horizontal">
</LinearLayout> </LinearLayout>
</HorizontalScrollView> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/issueDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen8dp"
android:autoLink="web"
android:gravity="start"
android:visibility="gone"
android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue"
android:textIsSelectable="true"
android:textSize="@dimen/dimen14sp" />
<HorizontalScrollView
android:id="@+id/labelsScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:foregroundGravity="right"
android:visibility="gone"
android:scrollbarThumbHorizontal="@android:color/transparent">
<LinearLayout
android:id="@+id/frameLabels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/commentReactionBadges"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen10dp"
android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout> </LinearLayout>

View File

@ -1,268 +1,269 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/loginForm"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="@drawable/login_bg">
android:gravity="center"
android:orientation="vertical"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:alpha="0.6" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:gravity="center"
android:layout_above="@id/card_view">
<ImageView <ImageView
android:layout_width="@dimen/dimen100dp" android:layout_width="@dimen/dimen80dp"
android:layout_height="@dimen/dimen100dp" android:layout_height="@dimen/dimen80dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dimen20dp"
android:layout_marginBottom="@dimen/dimen20dp"
android:baselineAligned="false" android:baselineAligned="false"
android:contentDescription="@string/appName" android:contentDescription="@string/appName"
android:src="@mipmap/app_logo"/> android:src="@mipmap/app_logo" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:text="@string/appName"
android:gravity="start" android:textStyle="bold"
android:text="@string/loginMethodText" android:textSize="@dimen/dimen24sp"
android:textColor="?attr/primaryTextColor" android:textColor="@color/colorWhite"
android:textSize="@dimen/dimen12sp"/> android:layout_marginTop="@dimen/dimen8dp" />
<RadioGroup
android:id="@+id/loginMethod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:orientation="vertical">
<RadioButton
android:id="@+id/loginToken"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen36dp"
android:checked="true"
android:text="@string/copyToken"
android:textColor="?attr/primaryTextColor"/>
<RadioButton
android:id="@+id/loginUsernamePassword"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen36dp"
android:text="@string/loginViaPassword"
android:textColor="?attr/primaryTextColor"/>
</RadioGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/httpsSpinnerLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/protocol"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<AutoCompleteTextView
android:id="@+id/httpsSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:labelFor="@+id/httpsSpinner"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/instance_urlLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/instanceUrl"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_link"
app:startIconTint="?attr/iconsColor"
app:helperText="@string/instanceHelperText">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/instance_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_uidLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userName"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_person"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/login_uid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_passwdLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/passWord"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="password_toggle"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/login_passwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/otpCodeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/loginOTP"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:helperText="@string/otpMessage"
app:helperTextEnabled="true"
app:helperTextTextColor="?attr/inputTextColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_otp"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/otpCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginTokenCodeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/copyToken"
android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/loginTokenCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/btnLogin"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen10dp"
android:layout_marginTop="@dimen/dimen20dp"
android:layout_marginEnd="@dimen/dimen10dp"
android:autoLink="web"
android:gravity="center"
android:text="@string/appRepoLink"
android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue"
android:textSize="@dimen/dimen14sp"/>
<TextView <TextView
android:id="@+id/appVersion" android:id="@+id/appVersion"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dimen6dp" android:layout_marginTop="@dimen/dimen6dp"
android:layout_weight="1" android:textColor="@color/colorWhite"
android:maxLines="1" android:textSize="@dimen/dimen12sp" />
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"/>
</LinearLayout> </LinearLayout>
</ScrollView> <com.google.android.material.card.MaterialCardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="-28dp"
android:alpha="0.9"
app:cardCornerRadius="@dimen/dimen32dp"
app:strokeWidth="@dimen/dimen0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dimen28dp">
<RadioGroup
android:id="@+id/loginMethod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/loginToken"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen36dp"
android:checked="true"
android:text="@string/copyToken"
android:layout_marginEnd="@dimen/dimen8dp"
android:textColor="?attr/inputTextColor" />
<RadioButton
android:id="@+id/loginUsernamePassword"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen36dp"
android:text="@string/loginViaPassword"
android:textColor="?attr/inputTextColor" />
</RadioGroup>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/httpsSpinnerLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/protocol"
android:textColorHint="?attr/hintColor"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor">
<AutoCompleteTextView
android:id="@+id/httpsSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:labelFor="@+id/httpsSpinner"
android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/instance_urlLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/instanceUrl"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_link"
app:startIconTint="?attr/iconsColor"
app:helperText="@string/instanceHelperText">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/instance_url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_uidLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/userName"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_person"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/login_uid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_passwdLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/passWord"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="password_toggle"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/login_passwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/otpCodeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/loginOTP"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:helperText="@string/otpMessage"
app:helperTextEnabled="true"
app:helperTextTextColor="?attr/inputTextColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_otp"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/otpCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginTokenCodeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/copyToken"
android:textColorHint="?attr/hintColor"
app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"
app:startIconDrawable="@drawable/ic_lock"
app:startIconTint="?attr/iconsColor">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/loginTokenCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen16dp"
android:text="@string/btnLogin"
android:textColor="?attr/materialCardBackgroundColor"
android:letterSpacing="0.1"
android:textStyle="bold" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>

View File

@ -1,72 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.SearchView" android:background="?attr/primaryBackgroundColor"
app:elevation="@dimen/dimen0dp"> android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/mergePullRequestButtonText"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:menu="@menu/create_issue_menu"
android:contentDescription="@string/close" app:navigationIcon="@drawable/ic_close" />
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<HorizontalScrollView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/replyToPRNavHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen0dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:fillViewport="true"
android:foregroundGravity="right"
android:scrollbarThumbHorizontal="@android:color/transparent">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</HorizontalScrollView>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/dimen16dp"> android:padding="@dimen/dimen16dp">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/mergeTitleLayout" android:id="@+id/mergeTitleLayout"
@ -76,7 +54,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/mergePullRequestButtonText" android:hint="@string/mergePullRequestButtonText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:counterEnabled="true" app:counterEnabled="true"
app:counterMaxLength="255" app:counterMaxLength="255"
@ -95,7 +72,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -107,7 +84,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/mergeCommentText" android:hint="@string/mergeCommentText"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -122,7 +98,7 @@
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textColorHighlight="?attr/hintColor" android:textColorHighlight="?attr/hintColor"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -135,7 +111,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/mergeStrategy" android:hint="@string/mergeStrategy"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">
@ -146,7 +121,7 @@
android:inputType="none" android:inputType="none"
android:labelFor="@+id/mergeSpinner" android:labelFor="@+id/mergeSpinner"
android:textColor="?attr/inputTextColor" android:textColor="?attr/inputTextColor"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -159,17 +134,17 @@
android:text="@string/deleteBranchAfterMerge" android:text="@string/deleteBranchAfterMerge"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp" android:textSize="@dimen/dimen16sp"
android:visibility="gone"/> android:visibility="gone" />
<TextView <TextView
android:id="@+id/deleteBranchForkInfo" android:id="@+id/deleteBranchForkInfo"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen0dp" android:layout_marginTop="@dimen/dimen10dp"
android:gravity="start" android:gravity="start"
android:text="@string/deleteBranchForkInfo" android:text="@string/deleteBranchForkInfo"
android:textColor="?attr/hintColor" android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp"/> android:textSize="@dimen/dimen12sp" />
<TextView <TextView
android:id="@+id/mergeInfo" android:id="@+id/mergeInfo"
@ -179,16 +154,7 @@
android:gravity="start" android:gravity="start"
android:text="@string/mergeNoteText" android:text="@string/mergeNoteText"
android:textColor="?attr/hintColor" android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp"/> android:textSize="@dimen/dimen12sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/mergeButton"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen54dp"
android:layout_marginTop="@dimen/dimen8dp"
android:text="@string/mergePullRequestButtonText"
android:textColor="?attr/materialCardBackgroundColor"
android:textStyle="bold"/>
<TextView <TextView
android:id="@+id/mergeInfoDisabledMessage" android:id="@+id/mergeInfoDisabledMessage"
@ -199,11 +165,11 @@
android:text="@string/mergeInfoDisabledMessage" android:text="@string/mergeInfoDisabledMessage"
android:textColor="?attr/hintColor" android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" android:textSize="@dimen/dimen12sp"
android:visibility="gone"/> android:visibility="visible" />
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,351 +1,299 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:background="?attr/primaryBackgroundColor"
android:theme="@style/Widget.AppCompat.SearchView" android:fitsSystemWindows="true">
app:elevation="@dimen/dimen0dp">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:theme="@style/AppTheme.AppBarOverlay"> app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/settingsAppearanceHeader"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:navigationIcon="@drawable/ic_close" />
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/settingsAppearanceHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:id="@+id/themeSelectionFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen6dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/themeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/themeSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/themeSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/themeSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/lightThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/lightThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsLightThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/lightThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/darkThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/darkThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsDarkThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/darkThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/customFontFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/customFontHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsCustomFontHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/customFontSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsCustomFontDefault"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragmentTabsAnimationFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/fragmentTabsAnimationFrameHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/fragmentTabsAnimationHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/fragmentTabsAnimationFrameSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/fadeOut"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/counterBadgeFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/tvCounterBadgeHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen48dp"
android:text="@string/settingsCounterBadges"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchCounterBadge"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen24dp"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:layout_toEndOf="@+id/tvCounterBadgeHeader"
android:gravity="end"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen24dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/labelsInListFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<LinearLayout <LinearLayout
android:id="@+id/label_title_frame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:weightSum="100" android:orientation="vertical"
android:orientation="horizontal"> android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/tvLabelsInListHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="90"
android:layout_marginStart="@dimen/dimen24dp"
android:text="@string/settingsLabelsInListHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:id="@+id/themeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="10" android:clickable="true"
android:gravity="center_vertical|end" android:focusable="true"
android:orientation="horizontal"> android:layout_marginTop="@dimen/dimen8dp"
android:orientation="vertical">
<com.google.android.material.materialswitch.MaterialSwitch <TextView
android:id="@+id/switchLabelsInListBadge" android:id="@+id/themeHeaderSelector"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/dimen32dp" android:layout_height="wrap_content"
android:paddingStart="@dimen/dimen24dp" android:text="@string/themeSelectionHeaderText"
android:paddingEnd="@dimen/dimen24dp" /> android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/themeSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/themeSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/lightThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/lightThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsLightThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/lightThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/darkThemeTimeSelectionFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/darkThemeTimeHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsDarkThemeTimeSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/darkThemeSelectedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/customFontFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/customFontHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsCustomFontHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/customFontSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsCustomFontDefault"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/fragmentTabsAnimationFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/fragmentTabsAnimationFrameHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fragmentTabsAnimationHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/fragmentTabsAnimationFrameSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fadeOut"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/counterBadgeFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tvCounterBadgeHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/settingsCounterBadges"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchCounterBadge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/settingsCounterBadges"
android:layout_weight=".10" />
</LinearLayout>
<LinearLayout
android:id="@+id/labelsInListFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tvLabelsInListHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/settingsLabelsInListHeader"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchLabelsInListBadge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/settingsLabelsInListHeader"
android:layout_weight=".10" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen96dp"
android:text="@string/settingsLabelsInListHint"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/langFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/tvLanguageHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsLanguageSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/tvLanguageSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsLanguageSelectedHeaderDefault"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<TextView
android:id="@+id/helpTranslate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="@dimen/dimen12dp"
android:text="@string/settingsHelpTranslateText"
android:textColor="@color/lightBlue"
android:textSize="@dimen/dimen16sp" />
</LinearLayout> </LinearLayout>
<TextView </androidx.core.widget.NestedScrollView>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/label_title_frame"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen84dp"
android:text="@string/settingsLabelsInListHint"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" />
</RelativeLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
<LinearLayout
android:id="@+id/langFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/tvLanguageHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsLanguageSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/tvLanguageSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsLanguageSelectedHeaderDefault"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<TextView
android:id="@+id/helpTranslate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:background="?android:attr/selectableItemBackground"
android:paddingStart="@dimen/dimen40dp"
android:paddingTop="@dimen/dimen12dp"
android:paddingBottom="@dimen/dimen12dp"
android:paddingEnd="@dimen/dimen24dp"
android:layout_marginBottom="@dimen/dimen2dp"
android:text="@string/settingsHelpTranslateText"
android:textColor="@color/lightBlue"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>

View File

@ -1,150 +1,133 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:background="?attr/primaryBackgroundColor"
android:theme="@style/Widget.AppCompat.SearchView" android:fitsSystemWindows="true">
app:elevation="@dimen/dimen0dp">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:theme="@style/AppTheme.AppBarOverlay"> app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/codeEditor"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:navigationIcon="@drawable/ic_close" />
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/codeEditor"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:id="@+id/ceColorSelectionFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen6dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView <LinearLayout
android:id="@+id/ceColorHeaderSelector" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:orientation="vertical"
android:layout_marginEnd="@dimen/dimen24dp" android:padding="@dimen/dimen16dp">
android:text="@string/ceSyntaxHighlightColor"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/ceColorSelected" android:id="@+id/ceColorSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:clickable="true"
android:layout_marginEnd="@dimen/dimen24dp" android:focusable="true"
android:text="@string/themeSelectionSelectedText" android:layout_marginTop="@dimen/dimen8dp"
android:textColor="?attr/selectedTextColor" android:orientation="vertical">
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/ceColorHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ceSyntaxHighlightColor"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<LinearLayout <TextView
android:id="@+id/indentationSelectionFrame" android:id="@+id/ceColorSelected"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:text="@string/themeSelectionSelectedText"
android:background="?android:attr/selectableItemBackground" android:textColor="?attr/selectedTextColor"
android:clickable="true" android:textSize="@dimen/dimen16sp" />
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/indentationHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/ceIndentation"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/indentationSelected" android:id="@+id/indentationSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen32dp"
android:layout_marginEnd="@dimen/dimen24dp" android:clickable="true"
android:text="@string/settingsThemeTimeSelectedHint" android:focusable="true"
android:textColor="?attr/selectedTextColor" android:orientation="vertical">
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/indentationHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ceIndentation"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <TextView
android:id="@+id/indentationTabsSelectionFrame" android:id="@+id/indentationSelected"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:text="@string/settingsThemeTimeSelectedHint"
android:background="?android:attr/selectableItemBackground" android:textColor="?attr/selectedTextColor"
android:clickable="true" android:textSize="@dimen/dimen16sp" />
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/indentationTabsHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/ceIndentationTabsWidth"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/indentationTabsSelected" android:id="@+id/indentationTabsSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen32dp"
android:layout_marginEnd="@dimen/dimen24dp" android:clickable="true"
android:text="@string/settingsThemeTimeSelectedHint" android:focusable="true"
android:textColor="?attr/selectedTextColor" android:orientation="vertical">
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/indentationTabsHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ceIndentationTabsWidth"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
</LinearLayout> <TextView
android:id="@+id/indentationTabsSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsThemeTimeSelectedHint"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,252 +1,213 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:background="?attr/primaryBackgroundColor"
android:theme="@style/Widget.AppCompat.SearchView" android:fitsSystemWindows="true">
app:elevation="@dimen/dimen0dp">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:theme="@style/AppTheme.AppBarOverlay"> app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/settingsGeneralHeader"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:navigationIcon="@drawable/ic_close" />
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbarTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/settingsGeneralHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:id="@+id/setDefaultLinkHandler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen6dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/generalDeepLinkDefaultScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:layout_marginBottom="@dimen/dimen6dp"
android:text="@string/generalDeepLinkDefaultScreen"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/generalDeepLinkDefaultScreenHintText"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp"/>
<TextView
android:id="@+id/generalDeepLinkSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/none"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/homeScreenFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/homeScreenHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsHomeScreenHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView
android:id="@+id/homeScreenSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsHomeScreenSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/customTabsFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/customTabsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen72dp"
android:text="@string/useCustomTabs"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchTabs"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen24dp"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:layout_toEndOf="@+id/customTabsHeader"
android:gravity="end"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen24dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/enableDraftsCommentsDeletion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<LinearLayout <LinearLayout
android:id="@+id/enableCommentsDeletionHeader"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:weightSum="100" android:orientation="vertical"
android:orientation="horizontal"> android:padding="@dimen/dimen16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="90"
android:layout_marginStart="@dimen/dimen24dp"
android:text="@string/settingsEnableCommentsDeletionText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:id="@+id/setDefaultLinkHandler"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="10" android:layout_marginTop="@dimen/dimen8dp"
android:gravity="center_vertical|end" android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/generalDeepLinkDefaultScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen4dp"
android:text="@string/generalDeepLinkDefaultScreen"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/generalDeepLinkDefaultScreenHintText"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" />
<TextView
android:id="@+id/generalDeepLinkSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/none"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/homeScreenFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/homeScreenHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsHomeScreenHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/homeScreenSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settingsHomeScreenSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/customTabsFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="horizontal"> android:orientation="horizontal">
<com.google.android.material.materialswitch.MaterialSwitch <TextView
android:id="@+id/commentsDeletionSwitch" android:id="@+id/customTabsHeader"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/dimen32dp" android:layout_height="wrap_content"
android:paddingStart="@dimen/dimen24dp" android:layout_weight=".90"
android:paddingEnd="@dimen/dimen24dp" /> android:text="@string/useCustomTabs"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchTabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/useCustomTabs"
android:layout_weight=".10" />
</LinearLayout>
<LinearLayout
android:id="@+id/enableDraftsCommentsDeletion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/settingsEnableCommentsDeletionText"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/commentsDeletionSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/settingsEnableCommentsDeletionText"
android:layout_weight=".10" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen96dp"
android:text="@string/settingsEnableCommentsDeletionHintText"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/enableSendReports"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="horizontal">
<TextView
android:id="@+id/enableReportsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/settingsEnableReportsText"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/crashReportsSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/settingsEnableReportsText"
android:layout_weight=".10" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView </androidx.core.widget.NestedScrollView>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/enableCommentsDeletionHeader"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen72dp"
android:text="@string/settingsEnableCommentsDeletionHintText"
android:textColor="?attr/hintColor"
android:textSize="@dimen/dimen12sp" />
</RelativeLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
<LinearLayout
android:id="@+id/enableSendReports"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:weightSum="100"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/enableReportsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="90"
android:layout_marginStart="@dimen/dimen24dp"
android:text="@string/settingsEnableReportsText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center_vertical|end"
android:orientation="horizontal">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/crashReportsSwitch"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen32dp"
android:paddingStart="@dimen/dimen24dp"
android:paddingEnd="@dimen/dimen24dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -1,219 +1,102 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:background="?attr/primaryBackgroundColor"
android:theme="@style/Widget.AppCompat.SearchView" android:fitsSystemWindows="true">
app:elevation="@dimen/dimen0dp">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:theme="@style/AppTheme.AppBarOverlay" app:contentScrim="?attr/primaryBackgroundColor"
tools:ignore="UnusedAttribute"> android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/pageTitleNotifications"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:navigationIcon="@drawable/ic_close" />
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close" />
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/pageTitleNotifications"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <androidx.core.widget.NestedScrollView
android:id="@+id/enableNotificationsFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen6dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:weightSum="100"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/enableNotificationsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="90"
android:layout_marginStart="@dimen/dimen24dp"
android:text="@string/enableNotificationsHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="10" android:orientation="vertical"
android:gravity="center_vertical|end" android:padding="@dimen/dimen16dp">
android:orientation="horizontal">
<com.google.android.material.materialswitch.MaterialSwitch <LinearLayout
android:id="@+id/enableNotificationsMode" android:id="@+id/enableNotificationsFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="@dimen/dimen32dp" android:layout_height="wrap_content"
android:paddingStart="@dimen/dimen24dp" android:orientation="horizontal">
android:paddingEnd="@dimen/dimen24dp" />
<TextView
android:id="@+id/enableNotificationsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/enableNotificationsHeaderText"
android:textColor="?attr/primaryTextColor"
android:layout_marginTop="@dimen/dimen4dp"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/enableNotificationsMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/enableNotificationsHeaderText"
android:layout_weight=".10" />
</LinearLayout>
<LinearLayout
android:id="@+id/pollingDelayFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen24dp"
android:orientation="vertical">
<TextView
android:id="@+id/pollingDelayHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/notificationsPollingHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/pollingDelaySelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pollingDelay15Minutes"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </androidx.core.widget.NestedScrollView>
<LinearLayout </androidx.coordinatorlayout.widget.CoordinatorLayout>
android:id="@+id/pollingDelayFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/pollingDelayHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/notificationsPollingHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<TextView
android:id="@+id/pollingDelaySelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/pollingDelaySelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
<RelativeLayout
android:id="@+id/enableLightsFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/enableLightsHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/enableLightsHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/enableLightsMode"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen24dp"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:layout_toEndOf="@+id/enableLightsHeader"
android:gravity="end"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen24dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/chooseColorFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/chooseColorHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/chooseColorSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/chooseColorState"
style="?attr/materialCardViewFilledStyle"
android:layout_width="@dimen/dimen28dp"
android:layout_height="@dimen/dimen28dp"
android:layout_alignEnd="@id/chooseColorHeader"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/dimen28dp"
android:gravity="end"
app:cardCornerRadius="@dimen/dimen16dp"
app:cardElevation="@dimen/dimen0dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/enableVibrationFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView
android:id="@+id/enableVibrationHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen72dp"
android:text="@string/enableVibrationHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/enableVibrationMode"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen24dp"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:layout_toEndOf="@+id/enableVibrationHeader"
android:gravity="end"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen24dp" />
</RelativeLayout>
</LinearLayout>

View File

@ -1,196 +1,169 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBackgroundColor" android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"> xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appBarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen10dp" android:background="?attr/primaryBackgroundColor"
android:theme="@style/Widget.AppCompat.SearchView" android:fitsSystemWindows="true">
app:elevation="@dimen/dimen0dp">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:background="?attr/primaryBackgroundColor"> android:background="?attr/primaryBackgroundColor"
app:contentScrim="?attr/primaryBackgroundColor"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize">
<ImageView <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/close" android:id="@+id/topAppBar"
android:layout_width="@dimen/dimen26dp" android:layout_width="match_parent"
android:layout_height="@dimen/dimen26dp" android:elevation="0dp"
android:layout_marginStart="@dimen/dimen16dp" android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="@dimen/dimen16dp" app:title="@string/settingsSecurityHeader"
android:background="?android:attr/selectableItemBackgroundBorderless" app:layout_collapseMode="pin"
android:clickable="true" app:navigationIcon="@drawable/ic_close" />
android:contentDescription="@string/close"
android:focusable="true"
android:gravity="center_vertical"
android:src="@drawable/ic_close"/>
<TextView </com.google.android.material.appbar.CollapsingToolbarLayout>
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="@string/settingsSecurityHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen20sp"/>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<RelativeLayout <androidx.core.widget.NestedScrollView
android:id="@+id/biometricFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dimen6dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/dimen16dp">
<TextView <LinearLayout
android:id="@+id/biometricHeader" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:orientation="vertical"
android:layout_marginEnd="@dimen/dimen72dp" android:padding="@dimen/dimen16dp">
android:text="@string/settingsBiometricHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<com.google.android.material.materialswitch.MaterialSwitch <LinearLayout
android:id="@+id/switchBiometric" android:id="@+id/biometricFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="@dimen/dimen24dp" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:orientation="horizontal">
android:layout_gravity="end"
android:layout_toEndOf="@+id/biometricHeader"
android:gravity="end"
android:paddingStart="@dimen/dimen0dp"
android:paddingEnd="@dimen/dimen24dp" />
</RelativeLayout> <TextView
android:id="@+id/biometricHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:text="@string/settingsBiometricHeader"
android:layout_marginTop="@dimen/dimen4dp"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/certsFrame" android:id="@+id/switchBiometric"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:contentDescription="@string/settingsBiometricHeader"
android:background="?android:attr/selectableItemBackground" android:layout_weight=".10" />
android:orientation="vertical"
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/tvCertHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/settingsCertsSelectorHeader"
android:textColor="?attr/primaryTextColor"
android:textSize="18sp"/>
</LinearLayout> <LinearLayout
android:id="@+id/certsFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen32dp"
android:orientation="vertical">
<LinearLayout <TextView
android:id="@+id/cacheSizeDataSelectionFrame" android:id="@+id/tvCertHeader"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:text="@string/settingsCertsSelectorHeader"
android:background="?android:attr/selectableItemBackground" android:textColor="?attr/primaryTextColor"
android:orientation="vertical" android:textSize="18sp" />
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/cacheSizeDataHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/cacheSizeDataSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/cacheSizeDataSelected" android:id="@+id/cacheSizeDataSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen32dp"
android:layout_marginEnd="@dimen/dimen24dp" android:orientation="vertical">
android:text="@string/cacheSizeDataSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/cacheSizeDataHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cacheSizeDataSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <TextView
android:id="@+id/cacheSizeImagesSelectionFrame" android:id="@+id/cacheSizeDataSelected"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:text="@string/cacheSizeDataSelectionSelectedText"
android:background="?android:attr/selectableItemBackground" android:textColor="?attr/selectedTextColor"
android:orientation="vertical" android:textSize="@dimen/dimen16sp" />
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/cacheSizeImagesHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/cacheSizeImagesSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/cacheSizeImagesSelected" android:id="@+id/cacheSizeImagesSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen32dp"
android:layout_marginEnd="@dimen/dimen24dp" android:orientation="vertical">
android:text="@string/cacheSizeImagesSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/cacheSizeImagesHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cacheSizeImagesSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
<LinearLayout <TextView
android:id="@+id/clearCacheSelectionFrame" android:id="@+id/cacheSizeImagesSelected"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen6dp" android:text="@string/cacheSizeImagesSelectionSelectedText"
android:background="?android:attr/selectableItemBackground" android:textColor="?attr/selectedTextColor"
android:orientation="vertical" android:textSize="@dimen/dimen16sp" />
android:padding="@dimen/dimen16dp">
<TextView </LinearLayout>
android:id="@+id/clearCacheHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp"
android:layout_marginEnd="@dimen/dimen24dp"
android:text="@string/clearCacheSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp"/>
<TextView <LinearLayout
android:id="@+id/clearCacheSelected" android:id="@+id/clearCacheSelectionFrame"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen32dp"
android:layout_marginEnd="@dimen/dimen24dp" android:orientation="vertical">
android:text="@string/clearCacheSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp"/>
</LinearLayout> <TextView
android:id="@+id/clearCacheHeaderSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clearCacheSelectionHeaderText"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen18sp" />
</LinearLayout> <TextView
android:id="@+id/clearCacheSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clearCacheSelectionSelectedText"
android:textColor="?attr/selectedTextColor"
android:textSize="@dimen/dimen16sp" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -124,7 +124,6 @@
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:hint="@string/newIssueTitle" android:hint="@string/newIssueTitle"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:endIconMode="clear_text" app:endIconMode="clear_text"
app:endIconTint="?attr/iconsColor" app:endIconTint="?attr/iconsColor"
@ -151,7 +150,6 @@
android:layout_marginTop="@dimen/dimen8dp" android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen8dp" android:layout_marginBottom="@dimen/dimen8dp"
android:textColorHint="?attr/hintColor" android:textColorHint="?attr/hintColor"
app:boxBackgroundColor="?attr/inputBackgroundColor"
app:boxStrokeErrorColor="@color/darkRed" app:boxStrokeErrorColor="@color/darkRed"
app:hintTextColor="?attr/hintColor"> app:hintTextColor="?attr/hintColor">

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBackgroundColor"
android:orientation="vertical"
android:paddingTop="@dimen/dimen4dp"
android:paddingBottom="@dimen/dimen12dp">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/dimen12dp"
android:paddingEnd="@dimen/dimen12dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/issuesAttachmentsHeadFrame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:padding="@dimen/dimen8dp">
<TextView
android:id="@+id/bottomSheetHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:text="@string/attachments"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen16sp" />
<com.google.android.material.card.MaterialCardView
style="?attr/materialCardViewFilledStyle"
android:layout_width="@dimen/dimen28dp"
android:layout_height="@dimen/dimen4dp"
android:layout_gravity="start"
android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginBottom="@dimen/dimen16dp"
app:cardCornerRadius="@dimen/dimen24dp"
app:cardElevation="@dimen/dimen0dp">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColor" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/materialCardViewElevatedStyle"
app:cardCornerRadius="@dimen/dimen24dp"
android:layout_gravity="end"
android:layout_marginStart="@dimen/dimen4dp"
android:layout_marginEnd="@dimen/dimen4dp"
app:cardElevation="@dimen/dimen0dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/fabColor"
android:padding="@dimen/dimen8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/add_attachment"
android:layout_width="@dimen/dimen24dp"
android:layout_height="@dimen/dimen24dp"
android:src="@drawable/ic_add"
android:contentDescription="@string/generalImgContentText"
app:tint="?attr/materialCardBackgroundColor" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen4dp"
android:padding="@dimen/dimen2dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dimen32dp"
android:layout_gravity="center"
android:contentDescription="@string/generalImgContentText" />
</LinearLayout>

View File

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto">
tools:context=".activities.RepoDetailActivity">
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -73,12 +73,11 @@
android:textColorLink="@color/lightBlue" android:textColorLink="@color/lightBlue"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp"/>
<View <com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen24dp" android:layout_marginTop="@dimen/dimen24dp"
android:layout_marginBottom="@dimen/dimen24dp" android:layout_marginBottom="@dimen/dimen24dp" />
android:background="?attr/dividerColor"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -101,85 +101,42 @@
android:layout_marginTop="@dimen/dimen20dp" android:layout_marginTop="@dimen/dimen20dp"
android:layout_marginBottom="@dimen/dimen0dp" android:layout_marginBottom="@dimen/dimen0dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"
android:baselineAligned="false"> android:baselineAligned="false">
<LinearLayout <com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/followers_section" android:id="@+id/metaInfoGroup"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:text="@string/profileTabFollowers"
android:textSize="@dimen/dimen14sp" />
<TextView
android:id="@+id/user_followers_count" android:id="@+id/user_followers_count"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:paddingTop="@dimen/dimen6dp"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/dimen14sp" /> android:text="@string/profileTabFollowers" />
</LinearLayout> <Button
<LinearLayout
android:id="@+id/following_section"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:text="@string/profileTabFollowing"
android:textSize="@dimen/dimen14sp" />
<TextView
android:id="@+id/user_following_count" android:id="@+id/user_following_count"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:paddingTop="@dimen/dimen6dp"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/dimen14sp" /> android:text="@string/profileTabFollowing" />
</LinearLayout> <Button
<LinearLayout
android:id="@+id/starred_repos_section"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor"
android:text="@string/starredRepos"
android:textSize="@dimen/dimen14sp" />
<TextView
android:id="@+id/user_starred_repos_count" android:id="@+id/user_starred_repos_count"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:paddingTop="@dimen/dimen6dp"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/dimen14sp" /> android:text="@string/starredRepos" />
</LinearLayout> </com.google.android.material.button.MaterialButtonToggleGroup>
</LinearLayout> </LinearLayout>

View File

@ -134,25 +134,17 @@
android:textColorLink="@color/lightBlue" android:textColorLink="@color/lightBlue"
android:textSize="@dimen/dimen16sp"/> android:textSize="@dimen/dimen16sp"/>
<com.google.android.material.card.MaterialCardView <org.mian.gitnex.helpers.languagestatistics.LanguageStatisticsBar
android:id="@+id/languages_statistic"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/dimen22dp"
style="?attr/materialCardViewElevatedStyle" android:layout_marginTop="@dimen/dimen4dp"
android:backgroundTint="@android:color/transparent" android:thumbTint="@android:color/transparent"
app:cardElevation="@dimen/dimen0dp"> android:clickable="false"
android:focusable="false"
<org.mian.gitnex.helpers.languagestatistics.LanguageStatisticsBar android:enabled="false"
android:id="@+id/languages_statistic" android:progressDrawable="@android:color/transparent"
android:layout_width="match_parent" android:visibility="gone" />
android:layout_height="wrap_content"
android:thumbTint="@android:color/transparent"
android:clickable="false"
android:focusable="false"
android:enabled="false"
android:progressDrawable="@android:color/transparent"
android:visibility="gone" />
</com.google.android.material.card.MaterialCardView>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -160,110 +152,55 @@
android:layout_marginTop="@dimen/dimen20dp" android:layout_marginTop="@dimen/dimen20dp"
android:layout_marginBottom="@dimen/dimen20dp" android:layout_marginBottom="@dimen/dimen20dp"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal"> android:gravity="center"
android:orientation="vertical">
<LinearLayout <com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/repoMetaStarsFrame" android:id="@+id/metaInfoGroup"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_weight="1"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/repoStargazersInMenu"
app:srcCompat="@drawable/ic_star_unfilled"/>
<TextView
android:id="@+id/repoMetaStars" android:id="@+id/repoMetaStars"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:textSize="@dimen/dimen14sp"/> android:textStyle="bold"
app:icon="@drawable/ic_star_unfilled"
android:text="@string/repoStars" />
</LinearLayout> <Button
<LinearLayout
android:id="@+id/repoMetaPullRequestsFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/tabPullRequests"
app:srcCompat="@drawable/ic_pull_request"/>
<TextView
android:id="@+id/repoMetaPullRequests" android:id="@+id/repoMetaPullRequests"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:textSize="@dimen/dimen14sp"/> android:textStyle="bold"
</LinearLayout> app:icon="@drawable/ic_pull_request"
android:text="@string/repoStars" />
<LinearLayout <Button
android:id="@+id/repoMetaForksFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/infoTabRepoForksCount"
app:srcCompat="@drawable/ic_fork"/>
<TextView
android:id="@+id/repoMetaForks" android:id="@+id/repoMetaForks"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:textSize="@dimen/dimen14sp"/> android:textStyle="bold"
app:icon="@drawable/ic_fork"
android:text="@string/repoStars" />
</LinearLayout> <Button
<LinearLayout
android:id="@+id/repoMetaWatchersFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/repoWatchersInMenu"
app:srcCompat="@drawable/ic_watchers"/>
<TextView
android:id="@+id/repoMetaWatchers" android:id="@+id/repoMetaWatchers"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/primaryTextColor" android:textSize="@dimen/dimen14sp"
android:textSize="@dimen/dimen14sp"/> android:textStyle="bold"
app:icon="@drawable/ic_watchers"
android:text="@string/repoStars" />
</LinearLayout> </com.google.android.material.button.MaterialButtonToggleGroup>
</LinearLayout> </LinearLayout>
@ -425,15 +362,25 @@
</LinearLayout> </LinearLayout>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/repoAdditionalButton" android:id="@+id/moreInfoFrame"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="@dimen/dimen54dp" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_marginTop="@dimen/dimen8dp"
android:layout_marginTop="@dimen/dimen6dp" android:layout_marginBottom="@dimen/dimen12dp"
android:layout_marginBottom="@dimen/dimen20dp" android:layout_gravity="center">
android:text="@string/infoShowMoreInformation"
android:textColor="?attr/materialCardBackgroundColor"/> <Button
android:id="@+id/repoAdditionalButton"
style="?attr/materialButtonToggleGroupStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/dimen14sp"
android:textStyle="bold"
app:icon="@drawable/ic_info"
android:text="@string/infoMoreInformation" />
</com.google.android.material.button.MaterialButtonToggleGroup>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fileFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen4dp"
android:paddingBottom="@dimen/dimen4dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/materialCardViewElevatedStyle"
app:cardElevation="@dimen/dimen0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dimen12dp"
android:orientation="horizontal">
<com.google.android.material.card.MaterialCardView
android:id="@+id/attachmentViewFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?attr/materialCardViewElevatedStyle"
android:visibility="gone"
android:layout_marginEnd="@dimen/dimen8dp"
app:cardElevation="@dimen/dimen0dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:orientation="horizontal">
<ImageView
android:id="@+id/attachment"
android:layout_width="@dimen/dimen36dp"
android:layout_height="@dimen/dimen36dp"
android:contentDescription="@string/generalImgContentText" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:id="@+id/filename_section"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".90"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/dimen48dp"
android:orientation="vertical">
<TextView
android:id="@+id/filename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defaultFilename"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp" />
</LinearLayout>
<ImageView
android:id="@+id/delete_attachment"
android:layout_width="@dimen/dimen20dp"
android:layout_height="@dimen/dimen20dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/dimen0dp"
android:contentDescription="@string/generalImgContentText"
android:src="@drawable/ic_delete" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View File

@ -2,7 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relativeLayoutFrameIssuesList" android:id="@+id/dashboardLayoutCardsFrame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="@dimen/dimen4dp" android:paddingTop="@dimen/dimen4dp"
@ -10,6 +10,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/cardLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="?attr/materialCardViewElevatedStyle" style="?attr/materialCardViewElevatedStyle"

View File

@ -35,8 +35,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor" android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical" android:orientation="vertical">
android:padding="@dimen/dimen12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/dimen12dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -64,8 +71,8 @@
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="15dp" android:layout_marginLeft="@dimen/dimen16dp"
android:layout_marginRight="15dp" android:layout_marginRight="@dimen/dimen16dp"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical"> android:orientation="vertical">
@ -77,7 +84,7 @@
android:ellipsize="middle" android:ellipsize="middle"
android:singleLine="true" android:singleLine="true"
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textSize="14sp" android:textSize="@dimen/dimen14sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
@ -87,7 +94,8 @@
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
android:textColor="?attr/hintColor" android:textColor="?attr/hintColor"
android:textSize="12sp" /> android:textSize="@dimen/dimen12sp" />
</LinearLayout> </LinearLayout>
<ImageView <ImageView
@ -111,16 +119,43 @@
android:textColor="?attr/primaryTextColor" android:textColor="?attr/primaryTextColor"
android:textColorLink="@color/lightBlue" android:textColorLink="@color/lightBlue"
android:textIsSelectable="true" android:textIsSelectable="true"
android:textSize="14sp" /> android:textSize="@dimen/dimen14sp" />
<LinearLayout <LinearLayout
android:id="@+id/commentReactionBadges" android:id="@+id/commentReactionBadges"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="@dimen/dimen16dp"
android:orientation="horizontal" android:orientation="horizontal"
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/attachmentFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/materialCardBackgroundColor"
android:foreground="?android:attr/selectableItemBackground"
android:visibility="gone"
android:orientation="vertical">
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen4dp" />
<LinearLayout
android:id="@+id/attachmentsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dimen12dp"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>

View File

@ -62,7 +62,7 @@
<View <View
android:id="@+id/spacer_view" android:id="@+id/spacer_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen8dp" /> android:layout_marginBottom="@dimen/dimen8dp" />
<LinearLayout <LinearLayout
@ -71,40 +71,45 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <LinearLayout
android:layout_width="@dimen/dimen18dp" android:id="@+id/repo_info_counter_frame"
android:layout_height="@dimen/dimen18dp" android:layout_width="wrap_content"
android:layout_marginStart="@dimen/dimen0dp" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen6dp" android:layout_weight=".90"
android:contentDescription="@string/generalImgContentText" android:orientation="horizontal">
app:srcCompat="@drawable/ic_trending"
app:tint="?attr/iconsColor" />
<TextView <ImageView
android:id="@+id/most_visited" android:layout_width="@dimen/dimen18dp"
android:layout_width="wrap_content" android:layout_height="@dimen/dimen18dp"
android:layout_height="wrap_content" android:layout_marginStart="@dimen/dimen0dp"
android:gravity="center_vertical" android:layout_marginEnd="@dimen/dimen6dp"
android:textColor="?attr/primaryTextColor" android:contentDescription="@string/generalImgContentText"
android:textSize="@dimen/dimen14sp" app:srcCompat="@drawable/ic_trending"
tools:text="@string/repoStars" /> app:tint="?attr/iconsColor" />
<TextView
android:id="@+id/most_visited"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/dimen14sp"
tools:text="@string/repoStars" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/repo_info_end_frame" android:id="@+id/repo_info_end_frame"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen10dp" android:layout_weight=".10"
android:gravity="center_vertical|end" android:gravity="end"
android:orientation="horizontal" android:orientation="horizontal">
android:paddingStart="@dimen/dimen6dp"
android:paddingEnd="@dimen/dimen0dp">
<ImageView <ImageView
android:id="@+id/reset_counter" android:id="@+id/reset_counter"
android:layout_width="@dimen/dimen18dp" android:layout_width="@dimen/dimen18dp"
android:layout_height="@dimen/dimen18dp" android:layout_height="@dimen/dimen18dp"
android:layout_marginStart="@dimen/dimen16dp"
android:layout_marginEnd="@dimen/dimen2dp"
android:contentDescription="@string/generalImgContentText" android:contentDescription="@string/generalImgContentText"
app:srcCompat="@drawable/ic_delete" app:srcCompat="@drawable/ic_delete"
app:tint="?attr/iconsColor" /> app:tint="?attr/iconsColor" />

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/addAccount"
android:orderInCategory="0"
android:title="@string/addNewAccountText"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/attachment"
android:icon="@drawable/ic_attachment"
android:orderInCategory="0"
android:title="@string/attachment"
app:showAsAction="ifRoom" />
<item
android:id="@+id/markdown"
android:icon="@drawable/ic_markdown"
android:orderInCategory="1"
android:title="@string/strMarkdown"
app:showAsAction="ifRoom" />
<item
android:id="@+id/create"
android:title="@string/newCreateButtonCopy"
android:orderInCategory="2"
android:contentDescription="@string/newCreateButtonCopy"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/create"
android:orderInCategory="0"
android:title="@string/newCreateButtonCopy"
android:contentDescription="@string/newCreateButtonCopy"
app:showAsAction="ifRoom" />
<item
android:id="@+id/update"
android:orderInCategory="1"
android:title="@string/newUpdateButtonCopy"
android:contentDescription="@string/newUpdateButtonCopy"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/markdown"
android:icon="@drawable/ic_markdown"
android:orderInCategory="0"
android:title="@string/strMarkdown"
app:showAsAction="ifRoom" />
<item
android:id="@+id/create"
android:orderInCategory="1"
android:title="@string/newCreateButtonCopy"
android:contentDescription="@string/newCreateButtonCopy" />
<item
android:id="@+id/create_tag"
android:orderInCategory="2"
android:title="@string/create_tag"
android:contentDescription="@string/create_tag" />
</menu>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/create"
android:title="@string/newCreateButtonCopy"
android:orderInCategory="0"
android:contentDescription="@string/newCreateButtonCopy"
app:showAsAction="ifRoom" />
<item
android:id="@+id/update"
android:title="@string/menuEditText"
android:orderInCategory="1"
android:contentDescription="@string/newCreateButtonCopy"
app:showAsAction="ifRoom" />
<item
android:id="@+id/delete"
android:title="@string/menuDeleteText"
android:orderInCategory="2"
android:contentDescription="@string/menuDeleteText"
app:showAsAction="ifRoom" />
</menu>

View File

@ -5,7 +5,6 @@
<item <item
android:id="@+id/save" android:id="@+id/save"
android:icon="@drawable/ic_save"
android:orderInCategory="1" android:orderInCategory="1"
android:title="@string/saveButton" android:title="@string/saveButton"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>

View File

@ -11,6 +11,7 @@
<dimen name="dimen16dp">16dp</dimen> <dimen name="dimen16dp">16dp</dimen>
<dimen name="dimen18dp">18dp</dimen> <dimen name="dimen18dp">18dp</dimen>
<dimen name="dimen20dp">20dp</dimen> <dimen name="dimen20dp">20dp</dimen>
<dimen name="dimen22dp">22dp</dimen>
<dimen name="dimen24dp">24dp</dimen> <dimen name="dimen24dp">24dp</dimen>
<dimen name="dimen26dp">26dp</dimen> <dimen name="dimen26dp">26dp</dimen>
<dimen name="dimen28dp">28dp</dimen> <dimen name="dimen28dp">28dp</dimen>

View File

@ -118,4 +118,191 @@
<item>@string/zoomOut</item> <item>@string/zoomOut</item>
<item>@string/none</item> <item>@string/none</item>
</string-array> </string-array>
<string-array name="notificationsPollingDelay">
<item>@string/pollingDelay15Minutes</item>
<item>@string/pollingDelay30Minutes</item>
<item>@string/pollingDelay45Minutes</item>
<item>@string/pollingDelay1Hour</item>
</string-array>
<string-array name="licenses">
<item>0BSD</item>
<item>AAL</item>
<item>ADSL</item>
<item>AFL-1.1</item>
<item>AFL-1.1</item>
<item>AFL-2.0</item>
<item>AFL-3.0</item>
<item>AGPL-1.0-only</item>
<item>AGPL-1.0-or-later</item>
<item>AGPL-3.0-only</item>
<item>AGPL-3.0-or-later</item>
<item>AML</item>
<item>APL-1.0</item>
<item>APSL-1.0</item>
<item>APSL-2.0</item>
<item>Adobe-2006</item>
<item>Aladdin</item>
<item>Apache-1.0</item>
<item>Apache-1.1</item>
<item>Apache-2.0</item>
<item>Artistic-1.0</item>
<item>Artistic-2.0</item>
<item>BSD-1-Clause</item>
<item>BSD-2-Clause</item>
<item>BSD-2-Clause-Patent</item>
<item>BSD-2-Clause-Views</item>
<item>BSD-3-Clause</item>
<item>BSD-3-Clause-Attribution</item>
<item>BSD-3-Clause-Clear</item>
<item>BSD-3-Clause-LBNL</item>
<item>BSD-3-Clause-Modification</item>
<item>BSD-3-Clause-No-Military-License</item>
<item>BSD-3-Clause-No-Nuclear-License</item>
<item>BSD-3-Clause-No-Nuclear-License-2014</item>
<item>BSD-3-Clause-No-Nuclear-Warranty</item>
<item>BSD-3-Clause-Open-MPI</item>
<item>BSD-3-Clause-Sun</item>
<item>BSD-4-Clause-Shortened</item>
<item>BSD-4-Clause-UC</item>
<item>BSD-4.3RENO</item>
<item>BSD-4.3TAHOE</item>
<item>BSD-Advertising-Acknowledgement</item>
<item>BSD-Attribution-HPND-disclaimer</item>
<item>BSD-Protection</item>
<item>BSD-Source-Code</item>
<item>BSD-Systemics</item>
<item>BitTorrent-1.0</item>
<item>BitTorrent-1.1</item>
<item>CC-BY-1.0</item>
<item>CC-BY-2.0</item>
<item>CC-BY-2.5</item>
<item>CC-BY-2.5-AU</item>
<item>CC-BY-3.0</item>
<item>CC-BY-3.0-AT</item>
<item>CC-BY-3.0-DE</item>
<item>CC-BY-4.0</item>
<item>CC-BY-NC-1.0</item>
<item>CC-BY-NC-2.0</item>
<item>CC-BY-NC-2.5</item>
<item>CC-BY-NC-3.0</item>
<item>CC-BY-NC-4.0</item>
<item>Community-Spec-1.0</item>
<item>Cube</item>
<item>D-FSL-1.0</item>
<item>DL-DE-BY-2.0</item>
<item>ECL-1.0</item>
<item>ECL-2.0</item>
<item>EFL-1.0</item>
<item>EFL-2.0</item>
<item>Elastic-2.0</item>
<item>FreeBSD-DOC</item>
<item>GD</item>
<item>GFDL-1.1-only</item>
<item>GFDL-1.1-or-later</item>
<item>GFDL-1.2-only</item>
<item>GFDL-1.2-or-later</item>
<item>GFDL-1.3-only</item>
<item>GFDL-1.3-or-later</item>
<item>GPL-1.0-only</item>
<item>GPL-1.0-or-later</item>
<item>GPL-2.0-only</item>
<item>GPL-2.0-or-later</item>
<item>GPL-3.0-interface-exception</item>
<item>GPL-3.0-only</item>
<item>GPL-3.0-or-later</item>
<item>GPL-CC-1.0</item>
<item>GStreamer-exception-2008</item>
<item>Glide</item>
<item>HP-1989</item>
<item>IBM-pibs</item>
<item>ICU</item>
<item>IPL-1.0</item>
<item>ImageMagick</item>
<item>Intel</item>
<item>Intel-ACPI</item>
<item>Interbase-1.0</item>
<item>JSON</item>
<item>LAL-1.3</item>
<item>LGPL-2.0-only</item>
<item>LGPL-2.0-or-later</item>
<item>LGPL-2.1-only</item>
<item>LGPL-2.1-or-later</item>
<item>LGPL-3.0-only</item>
<item>LGPL-3.0-or-later</item>
<item>LGPLLR</item>
<item>LLGPL</item>
<item>LPL-1.0</item>
<item>LPL-1.02</item>
<item>LPPL-1.0</item>
<item>LPPL-1.3a</item>
<item>LPPL-1.3c</item>
<item>Libpng</item>
<item>Linux-OpenIB</item>
<item>MIT</item>
<item>MIT-0</item>
<item>MIT-CMU</item>
<item>MIT-Festival</item>
<item>MIT-Modern-Variant</item>
<item>MIT-Wu</item>
<item>MIT-advertising</item>
<item>MIT-open-group</item>
<item>MPL-1.0</item>
<item>MPL-2.0</item>
<item>MirOS</item>
<item>NASA-1.3</item>
<item>NTP</item>
<item>Nokia</item>
<item>OCLC-2.0</item>
<item>OFL-1.0</item>
<item>OFL-1.1</item>
<item>OLDAP-1.1</item>
<item>OLDAP-2.0</item>
<item>OLDAP-2.8</item>
<item>OML</item>
<item>OSL-1.0</item>
<item>OSL-2.0</item>
<item>OSL-3.0</item>
<item>OpenSSL</item>
<item>PHP-3.0</item>
<item>PSF-2.0</item>
<item>PostgreSQL</item>
<item>Python-2.0</item>
<item>QPL-1.0</item>
<item>Qt-GPL-exception-1.0</item>
<item>Qt-GPL-exception-1.1</item>
<item>RPL-1.1</item>
<item>RPL-1.5</item>
<item>Ruby</item>
<item>SGI-B-1.0</item>
<item>SGI-B-2.0</item>
<item>SSH-OpenSSH</item>
<item>Sendmail</item>
<item>TCL</item>
<item>UnixCrypt</item>
<item>Unlicense</item>
<item>Vim</item>
<item>W3C</item>
<item>WTFPL</item>
<item>X11</item>
<item>XFree86-1.1</item>
<item>Xdebug-1.03</item>
<item>Xerox</item>
<item>YPL-1.0</item>
<item>ZPL-1.1</item>
<item>ZPL-2.0</item>
<item>Zed</item>
<item>Zimbra-1.4</item>
<item>Zlib</item>
<item>bzip2-1.0.6</item>
<item>copyleft-next-0.3.1</item>
<item>curl</item>
<item>gnuplot</item>
<item>libpng-2.0</item>
<item>libselinux-1.0</item>
<item>w3m</item>
<item>xpp</item>
<item>zlib-acknowledgement</item>
</string-array>
</resources> </resources>

View File

@ -72,6 +72,10 @@
<string name="newRepoDescTintCopy">Repository Description</string> <string name="newRepoDescTintCopy">Repository Description</string>
<string name="newRepoPrivateCopy">Private</string> <string name="newRepoPrivateCopy">Private</string>
<string name="newRepoOwner">Owner</string> <string name="newRepoOwner">Owner</string>
<string name="newRepoIssueLabels">Issue Labels</string>
<string name="advanced" translatable="false">Advanced</string>
<string name="defaultText" translatable="false">Default</string>
<string name="setAsTemplate">Make repository a template</string>
<string name="newOrgTintCopy">Organization Name</string> <string name="newOrgTintCopy">Organization Name</string>
<string name="newOrgDescTintCopy">Organization Description</string> <string name="newOrgDescTintCopy">Organization Description</string>
@ -103,6 +107,7 @@
<string name="repoCreated">Repository created successfully</string> <string name="repoCreated">Repository created successfully</string>
<string name="repoExistsError">Repository of this name already exists under selected Owner</string> <string name="repoExistsError">Repository of this name already exists under selected Owner</string>
<string name="repoOwnerError">Select owner for the repository</string> <string name="repoOwnerError">Select owner for the repository</string>
<string name="repoDefaultBranchError">The default branch must not be empty</string>
<string name="orgNameErrorEmpty">Organization name is empty</string> <string name="orgNameErrorEmpty">Organization name is empty</string>
<string name="orgNameErrorInvalid">Organization name is not valid, [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string> <string name="orgNameErrorInvalid">Organization name is not valid, [a&#8211;z A&#8211;Z 0&#8211;9 &#8211; _]</string>
@ -144,7 +149,6 @@
<string name="infoTabRepoUpdatedAt">Last Updated</string> <string name="infoTabRepoUpdatedAt">Last Updated</string>
<string name="infoTabRepoZero" translatable="false">0</string> <string name="infoTabRepoZero" translatable="false">0</string>
<string name="infoShowMoreInformation">Show More Information</string>
<string name="infoMoreInformation">More Information</string> <string name="infoMoreInformation">More Information</string>
<string name="timeAtText">at</string> <string name="timeAtText">at</string>
@ -524,6 +528,8 @@
<string name="reset">Reset</string> <string name="reset">Reset</string>
<string name="beta">BETA</string> <string name="beta">BETA</string>
<string name="none">None</string> <string name="none">None</string>
<string name="main">main</string>
<string name="license">License</string>
<!-- generic copy --> <!-- generic copy -->
<string name="exploreUsers">Explore users</string> <string name="exploreUsers">Explore users</string>
@ -541,8 +547,7 @@
<string name="versionUnknown">No Gitea detected!</string> <string name="versionUnknown">No Gitea detected!</string>
<string name="versionAlertDialogHeader">Unsupported Version of Gitea</string> <string name="versionAlertDialogHeader">Unsupported Version of Gitea</string>
<string name="loginViaPassword">Username / Password</string> <string name="loginViaPassword">Basic Auth</string>
<string name="loginMethodText">Choose your preferred login method to access your account. Token is more secure!</string>
<string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</string> <string name="unauthorizedApiError">Instance has returned an error - Unauthorized. Check your credentials and try again</string>
<string name="loginTokenError">Token is required</string> <string name="loginTokenError">Token is required</string>
@ -651,7 +656,7 @@
<string name="removeAccountPopupTitle">Remove Account</string> <string name="removeAccountPopupTitle">Remove Account</string>
<string name="removeAccountPopupMessage">Are you sure you want to remove this account from the app?\n\nThis will remove all the data related to this account on the app only.</string> <string name="removeAccountPopupMessage">Are you sure you want to remove this account from the app?\n\nThis will remove all the data related to this account on the app only.</string>
<string name="addNewAccount">New Account</string> <string name="addNewAccount">New Account</string>
<string name="addNewAccountText">Add New Account</string> <string name="addNewAccountText">Add Account</string>
<string name="accountAlreadyExistsError">Account already exists in the app</string> <string name="accountAlreadyExistsError">Account already exists in the app</string>
<string name="accountAddedMessage">Account added successfully</string> <string name="accountAddedMessage">Account added successfully</string>
<string name="switchAccountSuccess">Switched to account : %1$s@%2$s</string> <string name="switchAccountSuccess">Switched to account : %1$s@%2$s</string>
@ -660,14 +665,17 @@
<string name="pageTitleNotifications">Notifications</string> <string name="pageTitleNotifications">Notifications</string>
<string name="noDataNotifications">All caught up 🚀</string> <string name="noDataNotifications">All caught up 🚀</string>
<string name="notificationsPollingHeaderText">Notifications Polling Delay</string> <string name="notificationsPollingHeaderText">Notifications Polling Delay</string>
<string name="pollingDelaySelectedText">%d Minutes</string> <string name="pollingDelay15Minutes">15 Minutes</string>
<string name="pollingDelay30Minutes">30 Minutes</string>
<string name="pollingDelay45Minutes">45 Minutes</string>
<string name="pollingDelay1Hour">1 Hour</string>
<string name="pollingDelayDialogHeaderText">Select Polling Delay</string> <string name="pollingDelayDialogHeaderText">Select Polling Delay</string>
<string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string> <string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string>
<string name="markAsRead">Mark Read</string> <string name="markAsRead">Mark Read</string>
<string name="markAsUnread">Mark Unread</string> <string name="markAsUnread">Mark Unread</string>
<string name="pinNotification">Pin</string> <string name="pinNotification">Pin</string>
<string name="markedNotificationsAsRead">Successfully marked all notifications as read</string> <string name="markedNotificationsAsRead">Successfully marked all notifications as read</string>
<string name="notificationsHintText">Polling delay, light, vibration</string> <string name="notificationsHintText">Polling delay</string>
<string name="enableNotificationsHeaderText">Enable Notifications</string> <string name="enableNotificationsHeaderText">Enable Notifications</string>
<string name="enableLightsHeaderText">Enable Light</string> <string name="enableLightsHeaderText">Enable Light</string>
<string name="enableVibrationHeaderText">Enable Vibration</string> <string name="enableVibrationHeaderText">Enable Vibration</string>
@ -681,6 +689,7 @@
<item quantity="one">You have %s new notification</item> <item quantity="one">You have %s new notification</item>
<item quantity="other">You have %s new notifications</item> <item quantity="other">You have %s new notifications</item>
</plurals> </plurals>
<string name="openAppSettings">To receive notifications, you must enable notifications for GitNex. Tap Open to access your phone settings and enable notifications.</string>
<string name="isRead">Read</string> <string name="isRead">Read</string>
<string name="isUnread">Unread</string> <string name="isUnread">Unread</string>
@ -865,6 +874,7 @@
<string name="timelineRefIssue">%1$s referenced this issue in #%2$d %3$s</string> <string name="timelineRefIssue">%1$s referenced this issue in #%2$d %3$s</string>
<string name="timelineRefPr">%1$s referenced this pull request in #%2$d %3$s</string> <string name="timelineRefPr">%1$s referenced this pull request in #%2$d %3$s</string>
<string name="timelineStatusRefIssue"><![CDATA[%1$s referenced this issue from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string> <string name="timelineStatusRefIssue"><![CDATA[%1$s referenced this issue from a <font color=\'%2$d\'>%3$s</font> %4$s]]></string>
<string name="timelineReviewLeftComment">%1$s left a comment: %2$s %3$s</string>
<string name="commitStatuses">Statuses</string> <string name="commitStatuses">Statuses</string>
<string name="statusNoUrl">This status has no linked target URL.</string> <string name="statusNoUrl">This status has no linked target URL.</string>
@ -875,4 +885,33 @@
<string name="lang_percentage" translatable="false">%s%%</string> <string name="lang_percentage" translatable="false">%s%%</string>
<string name="dashboard">Dashboard</string> <string name="dashboard">Dashboard</string>
<string name="createdRepository">created repository</string>
<string name="renamedRepository">renamed repository from %1$s to</string>
<string name="starredRepository">starred</string>
<string name="transferredRepository">transferred repository %1$s to</string>
<string name="createdBranch">created branch %1$s in</string>
<string name="pushedTo">pushed to %1$s at</string>
<string name="openedIssue">opened issue</string>
<string name="commentedOnIssue">commented on issue</string>
<string name="closedIssue">closed issue</string>
<string name="reopenedIssue">reopened issue</string>
<string name="createdPR">created pull request</string>
<string name="closedPR">closed pull request</string>
<string name="reopenedPR">reopened pull request</string>
<string name="mergedPR">merged pull request</string>
<string name="approved">approved</string>
<string name="suggestedChanges">suggested changes for</string>
<string name="commentedOnPR">commented on pull request</string>
<string name="autoMergePR">automatically merged pull request</string>
<string name="deletedBranch">deleted branch %1$s at</string>
<string name="pushedTag">pushed tag %1$s to</string>
<string name="deletedTag">deleted tag %1$s from</string>
<string name="releasedBranch">released %1$s at</string>
<string name="syncedCommits">synced commits to %1$s at</string>
<string name="syncedRefs">synced new reference %1$s to</string>
<string name="syncedDeletedRefs">synced and deleted reference %1$s at</string>
<string name="attachment">Attachment</string>
<string name="attachments">Attachments</string>
<string name="attachmentsSaveError">An issue was created but cannot process attachments at this time. Check the server logs for more details.</string>
</resources> </resources>

View File

@ -7,7 +7,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.0.2' classpath 'com.android.tools.build:gradle:8.1.2'
} }
} }
@ -19,6 +19,6 @@ allprojects {
} }
} }
task clean(type: Delete) { tasks.register('clean', Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }