diff --git a/app/build.gradle b/app/build.gradle index 55212400..61fff840 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -139,7 +139,6 @@ dependencies { implementation "androidx.camera:camera-camera2:$cameraxVersion" implementation "androidx.camera:camera-lifecycle:$cameraxVersion" implementation "androidx.camera:camera-view:$cameraxVersion" - implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.core:core:1.12.0" implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.documentfile:documentfile:1.0.1' @@ -162,8 +161,6 @@ dependencies { implementation 'com.google.android.material:material:1.11.0' implementation 'com.google.protobuf:protobuf-javalite:3.25.1' implementation 'com.google.zxing:core:3.5.2' - implementation "com.mikepenz:iconics-core:3.2.5" - implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.5@aar' implementation 'com.nulab-inc:zxcvbn:1.8.2' implementation 'de.hdodenhof:circleimageview:3.1.0' implementation 'de.psdev.licensesdialog:licensesdialog:2.2.0' diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java index 001facd6..a7322c3c 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java @@ -2,15 +2,19 @@ package com.beemdevelopment.aegis; import android.view.View; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; +import androidx.test.espresso.matcher.BoundedMatcher; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.GrantPermissionRule; import com.beemdevelopment.aegis.crypto.CryptoUtils; import com.beemdevelopment.aegis.crypto.SCryptParameters; import com.beemdevelopment.aegis.otp.OtpInfo; +import com.beemdevelopment.aegis.ui.views.EntryHolder; import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.VaultFileCredentials; import com.beemdevelopment.aegis.vault.VaultManager; @@ -20,6 +24,7 @@ import com.beemdevelopment.aegis.vault.slots.PasswordSlot; import com.beemdevelopment.aegis.vault.slots.SlotException; import com.beemdevelopment.aegis.vectors.VaultEntries; +import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; @@ -178,4 +183,21 @@ public abstract class AegisTest { } }; } + + @NonNull + protected static Matcher withOtpType(Class otpClass) { + return new BoundedMatcher(EntryHolder.class) { + @Override + public boolean matchesSafely(EntryHolder holder) { + return holder != null + && holder.getEntry() != null + && holder.getEntry().getInfo().getClass().equals(otpClass); + } + + @Override + public void describeTo(Description description) { + description.appendText(String.format("with otp type '%s'", otpClass.getSimpleName())); + } + }; + } } diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java index 643adb49..6c12809e 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java @@ -1,7 +1,6 @@ package com.beemdevelopment.aegis; import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; import static androidx.test.espresso.Espresso.openContextualActionModeOverflowMenu; import static androidx.test.espresso.action.ViewActions.clearText; import static androidx.test.espresso.action.ViewActions.click; @@ -18,19 +17,17 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNull; import static junit.framework.TestCase.assertTrue; - import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import androidx.annotation.IdRes; -import androidx.test.core.app.ApplicationProvider; +import androidx.recyclerview.widget.RecyclerView; import androidx.test.espresso.ViewInteraction; import androidx.test.espresso.contrib.RecyclerViewActions; import androidx.test.espresso.matcher.RootMatchers; import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; -import androidx.test.platform.app.InstrumentationRegistry; import com.beemdevelopment.aegis.encoding.Base32; import com.beemdevelopment.aegis.encoding.Hex; @@ -41,6 +38,7 @@ import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.otp.YandexInfo; import com.beemdevelopment.aegis.rules.ScreenshotTestRule; import com.beemdevelopment.aegis.ui.MainActivity; +import com.beemdevelopment.aegis.ui.views.EntryAdapter; import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.VaultRepository; import com.beemdevelopment.aegis.vault.slots.PasswordSlot; @@ -55,6 +53,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; import dagger.hilt.android.testing.HiltAndroidTest; @@ -104,13 +103,19 @@ public class OverallTest extends AegisTest { } for (int i = 0; i < 10; i++) { - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(1, clickChildViewWithId(R.id.buttonRefresh))); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnHolderItem(withOtpType(HotpInfo.class), clickChildViewWithId(R.id.buttonRefresh))); } - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(0, longClick())); + AtomicBoolean isErrorCardShown = new AtomicBoolean(false); + _activityRule.getScenario().onActivity(activity -> { + isErrorCardShown.set(((EntryAdapter)((RecyclerView) activity.findViewById(R.id.rvKeyProfiles)).getAdapter()).isErrorCardShown()); + }); + + int entryPosOffset = isErrorCardShown.get() ? 1 : 0; + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 0, longClick())); onView(withId(R.id.action_copy)).perform(click()); - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(1, longClick())); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 1, longClick())); onView(withId(R.id.action_edit)).perform(click()); onView(withId(R.id.text_name)).perform(clearText(), typeText("Bob"), closeSoftKeyboard()); onView(withId(R.id.dropdown_group)).perform(click()); @@ -129,13 +134,13 @@ public class OverallTest extends AegisTest { changeGroupFilter(_groupName); changeGroupFilter(null); - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(2, longClick())); - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(3, click())); - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(4, click())); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 2, longClick())); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 3, click())); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 4, click())); onView(withId(R.id.action_share_qr)).perform(click()); onView(withId(R.id.btnNext)).perform(click()).perform(click()).perform(click()); - onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(0, longClick())); + onView(withId(R.id.rvKeyProfiles)).perform(RecyclerViewActions.actionOnItemAtPosition(entryPosOffset + 0, longClick())); onView(allOf(isDescendantOfA(withClassName(containsString("ActionBarContextView"))), withClassName(containsString("OverflowMenuButton")))).perform(click()); onView(withText(R.string.action_delete)).perform(click()); onView(withId(android.R.id.button1)).perform(click()); diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 36e70d77..5746551c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,8 +27,6 @@ android:icon="@mipmap/${iconName}" android:label="Aegis" android:supportsRtl="true" - android:theme="@style/Theme.Aegis.Launch" - tools:replace="android:theme" tools:targetApi="tiramisu"> diff --git a/app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java b/app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java index f7ba8ce4..2d973fa7 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java +++ b/app/src/main/java/com/beemdevelopment/aegis/AegisApplicationBase.java @@ -22,8 +22,6 @@ import com.beemdevelopment.aegis.receivers.VaultLockReceiver; import com.beemdevelopment.aegis.ui.MainActivity; import com.beemdevelopment.aegis.util.IOUtils; import com.beemdevelopment.aegis.vault.VaultManager; -import com.mikepenz.iconics.Iconics; -import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; import com.topjohnwu.superuser.Shell; import java.util.Collections; @@ -48,9 +46,6 @@ public abstract class AegisApplicationBase extends Application { super.onCreate(); _vaultManager = EarlyEntryPoints.get(this, EntryPoint.class).getVaultManager(); - Iconics.init(this); - Iconics.registerFont(new MaterialDesignIconic()); - VaultLockReceiver lockReceiver = new VaultLockReceiver(); IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); ContextCompat.registerReceiver(this, lockReceiver, intentFilter, ContextCompat.RECEIVER_NOT_EXPORTED); diff --git a/app/src/main/java/com/beemdevelopment/aegis/Preferences.java b/app/src/main/java/com/beemdevelopment/aegis/Preferences.java index 29ec0756..befc3522 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/Preferences.java +++ b/app/src/main/java/com/beemdevelopment/aegis/Preferences.java @@ -145,6 +145,10 @@ public class Preferences { return CodeGrouping.valueOf(value); } + public void setCodeGroupSize(CodeGrouping codeGroupSize) { + _prefs.edit().putString("pref_code_group_size_string", codeGroupSize.name()).apply(); + } + public boolean isIntroDone() { return _prefs.getBoolean("pref_intro", false); } @@ -198,6 +202,10 @@ public class Preferences { _prefs.edit().putInt("pref_current_theme", theme.ordinal()).apply(); } + public boolean isDynamicColorsEnabled() { + return _prefs.getBoolean("pref_dynamic_colors", false); + } + public ViewMode getCurrentViewMode() { return ViewMode.fromInteger(_prefs.getInt("pref_current_view_mode", 0)); } @@ -266,8 +274,16 @@ public class Preferences { return _prefs.getInt("pref_timeout", -1); } + public String getLanguage() { + return _prefs.getString("pref_lang", "system"); + } + + public void setLanguage(String lang) { + _prefs.edit().putString("pref_lang", lang).apply(); + } + public Locale getLocale() { - String lang = _prefs.getString("pref_lang", "system"); + String lang = getLanguage(); if (lang.equals("system")) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java b/app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java index 65b77625..52ac054c 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ThemeMap.java @@ -10,20 +10,14 @@ public class ThemeMap { } public static final Map DEFAULT = ImmutableMap.of( - Theme.LIGHT, R.style.Theme_Aegis_Light_Default, - Theme.DARK, R.style.Theme_Aegis_Dark_Default, - Theme.AMOLED, R.style.Theme_Aegis_TrueDark_Default - ); - - public static final Map NO_ACTION_BAR = ImmutableMap.of( - Theme.LIGHT, R.style.Theme_Aegis_Light_NoActionBar, - Theme.DARK, R.style.Theme_Aegis_Dark_NoActionBar, - Theme.AMOLED, R.style.Theme_Aegis_TrueDark_NoActionBar + Theme.LIGHT, R.style.Theme_Aegis_Light, + Theme.DARK, R.style.Theme_Aegis_Dark, + Theme.AMOLED, R.style.Theme_Aegis_Amoled ); public static final Map FULLSCREEN = ImmutableMap.of( Theme.LIGHT, R.style.Theme_Aegis_Light_Fullscreen, Theme.DARK, R.style.Theme_Aegis_Dark_Fullscreen, - Theme.AMOLED, R.style.Theme_Aegis_TrueDark_Fullscreen + Theme.AMOLED, R.style.Theme_Aegis_Amoled_Fullscreen ); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ViewMode.java b/app/src/main/java/com/beemdevelopment/aegis/ViewMode.java index 9d349850..f1d060c5 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ViewMode.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ViewMode.java @@ -44,7 +44,7 @@ public enum ViewMode { return 4; } - return 20; + return 8; } public int getColumnSpan() { diff --git a/app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java b/app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java index 959f2cf8..3192864f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java +++ b/app/src/main/java/com/beemdevelopment/aegis/helpers/SimpleItemTouchHelperCallback.java @@ -56,16 +56,20 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { // It's not clear when this can happen, but sometimes the ViewHolder // that's passed to this function has a position of -1, leading // to a crash down the line. - int position = viewHolder.getAdapterPosition(); + int position = viewHolder.getBindingAdapterPosition(); if (position == NO_POSITION) { return 0; } - int swipeFlags = 0; - EntryAdapter adapter = (EntryAdapter) recyclerView.getAdapter(); + if (adapter == null) { + return 0; + } + + int swipeFlags = 0; if (adapter.isPositionFooter(position) - || adapter.getEntryAt(position) != _selectedEntry + || adapter.isPositionErrorCard(position) + || adapter.getEntryAtPos(position) != _selectedEntry || !isLongPressDragEnabled()) { return makeMovementFlags(0, swipeFlags); } @@ -76,12 +80,13 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { - if (target.getAdapterPosition() < _adapter.getShownFavoritesCount()){ + int targetIndex = _adapter.translateEntryPosToIndex(target.getBindingAdapterPosition()); + if (targetIndex < _adapter.getShownFavoritesCount()) { return false; } int firstPosition = viewHolder.getLayoutPosition(); - int secondPosition = target.getAdapterPosition(); + int secondPosition = target.getBindingAdapterPosition(); _adapter.onItemMove(firstPosition, secondPosition); _positionChanged = true; @@ -90,7 +95,7 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { - _adapter.onItemDismiss(viewHolder.getAdapterPosition()); + _adapter.onItemDismiss(viewHolder.getBindingAdapterPosition()); } @Override @@ -98,7 +103,7 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { super.clearView(recyclerView, viewHolder); if (_positionChanged) { - _adapter.onItemDrop(viewHolder.getAdapterPosition()); + _adapter.onItemDrop(viewHolder.getBindingAdapterPosition()); _positionChanged = false; _adapter.refresh(false); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java b/app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java index aad90a55..2be31b0f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java @@ -21,6 +21,7 @@ import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.tasks.PBKDFTask; import com.beemdevelopment.aegis.util.IOUtils; import com.beemdevelopment.aegis.vault.VaultEntry; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.topjohnwu.superuser.io.SuFile; import org.json.JSONArray; @@ -182,7 +183,7 @@ public class AndOtpImporter extends DatabaseImporter { context.getResources().getString(R.string.andotp_old_format) }; - Dialogs.showSecureDialog(new AlertDialog.Builder(context) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(context) .setTitle(R.string.choose_andotp_importer) .setSingleChoiceItems(choices, 0, null) .setPositiveButton(android.R.string.ok, (dialog, which) -> { diff --git a/app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java b/app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java index b603eb86..699f39b2 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/importers/TotpAuthenticatorImporter.java @@ -4,8 +4,6 @@ import android.content.Context; import android.content.pm.PackageManager; import android.util.Xml; -import androidx.appcompat.app.AlertDialog; - import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.crypto.CryptoUtils; import com.beemdevelopment.aegis.encoding.Base32; @@ -18,6 +16,7 @@ import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.util.IOUtils; import com.beemdevelopment.aegis.util.PreferenceParser; import com.beemdevelopment.aegis.vault.VaultEntry; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.topjohnwu.superuser.io.SuFile; import org.json.JSONArray; @@ -154,7 +153,7 @@ public class TotpAuthenticatorImporter extends DatabaseImporter { @Override public void decrypt(Context context, DecryptListener listener) { - Dialogs.showSecureDialog(new AlertDialog.Builder(context) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(context) .setMessage(R.string.choose_totpauth_importer) .setPositiveButton(R.string.yes, (dialog, which) -> { Dialogs.showPasswordInputDialog(context, password -> { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java index 616717a1..1c1fd15e 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/AboutActivity.java @@ -13,17 +13,14 @@ import android.widget.Toast; import androidx.annotation.AttrRes; import androidx.annotation.StringRes; -import androidx.core.view.LayoutInflaterCompat; import com.beemdevelopment.aegis.BuildConfig; import com.beemdevelopment.aegis.R; -import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.helpers.ThemeHelper; import com.beemdevelopment.aegis.licenses.GlideLicense; import com.beemdevelopment.aegis.licenses.ProtobufLicense; import com.beemdevelopment.aegis.ui.dialogs.ChangelogDialog; import com.beemdevelopment.aegis.ui.dialogs.LicenseDialog; -import com.mikepenz.iconics.context.IconicsLayoutInflater2; import de.psdev.licensesdialog.LicenseResolver; import de.psdev.licensesdialog.LicensesDialog; @@ -40,7 +37,6 @@ public class AboutActivity extends AegisActivity { @Override protected void onCreate(Bundle savedInstanceState) { - LayoutInflaterCompat.setFactory2(getLayoutInflater(), new IconicsLayoutInflater2(getDelegate())); super.onCreate(savedInstanceState); if (abortIfOrphan(savedInstanceState)) { return; @@ -132,11 +128,10 @@ public class AboutActivity extends AegisActivity { private void showThirdPartyLicenseDialog() { String stylesheet = getString(R.string.custom_notices_format_style); - int backgroundColorResource = getConfiguredTheme() == Theme.AMOLED ? R.attr.cardBackgroundFocused : R.attr.cardBackground; - String backgroundColor = getThemeColorAsHex(backgroundColorResource); - String textColor = getThemeColorAsHex(R.attr.primaryText); - String licenseColor = getThemeColorAsHex(R.attr.cardBackgroundFocused); - String linkColor = getThemeColorAsHex(androidx.appcompat.R.attr.colorAccent); + String backgroundColor = getThemeColorAsHex(com.google.android.material.R.attr.colorSurfaceContainerLow); + String textColor = getThemeColorAsHex(com.google.android.material.R.attr.colorOnSurface); + String licenseColor = getThemeColorAsHex(com.google.android.material.R.attr.colorSurfaceContainerLow); + String linkColor = getThemeColorAsHex(com.google.android.material.R.attr.colorAccent); stylesheet = String.format(stylesheet, backgroundColor, textColor, licenseColor, linkColor); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java index 33b6fe85..ca4af1d5 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java @@ -4,21 +4,31 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.res.Configuration; +import android.os.Build; import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Toast; import androidx.annotation.CallSuper; +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ActionMode; +import androidx.core.view.ViewPropertyAnimatorCompat; import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.ThemeMap; +import com.beemdevelopment.aegis.helpers.ThemeHelper; import com.beemdevelopment.aegis.icons.IconPackManager; import com.beemdevelopment.aegis.vault.VaultManager; import com.beemdevelopment.aegis.vault.VaultRepositoryException; +import com.google.android.material.color.DynamicColors; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Locale; @@ -42,6 +52,8 @@ public abstract class AegisActivity extends AppCompatActivity implements VaultMa @Inject protected IconPackManager _iconPackManager; + private ActionModeStatusGuardHack _statusGuardHack; + @Override protected void onCreate(Bundle savedInstanceState) { // set the theme and locale before creating the activity @@ -50,6 +62,8 @@ public abstract class AegisActivity extends AppCompatActivity implements VaultMa setLocale(_prefs.getLocale()); super.onCreate(savedInstanceState); + _statusGuardHack = new ActionModeStatusGuardHack(); + // set FLAG_SECURE on the window of every AegisActivity if (_prefs.isSecureScreenEnabled()) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); @@ -106,6 +120,10 @@ public abstract class AegisActivity extends AppCompatActivity implements VaultMa protected void setTheme(Map themeMap) { int theme = themeMap.get(getConfiguredTheme()); setTheme(theme); + + if (_prefs.isDynamicColorsEnabled()) { + DynamicColors.applyToActivityIfAvailable(this); + } } protected Theme getConfiguredTheme() { @@ -169,6 +187,77 @@ public abstract class AegisActivity extends AppCompatActivity implements VaultMa return true; } + @Override + public void onSupportActionModeStarted(@NonNull ActionMode mode) { + super.onSupportActionModeStarted(mode); + _statusGuardHack.apply(View.VISIBLE); + } + + @Override + public void onSupportActionModeFinished(@NonNull ActionMode mode) { + super.onSupportActionModeFinished(mode); + _statusGuardHack.apply(View.GONE); + } + + /** + * When starting/finishing an action mode, forcefully cancel the fade in/out animation and + * set the status bar color. This requires the abc_decor_view_status_guard colors to be set + * to transparent. + * + * This should fix any inconsistencies between the color of the action bar and the status bar + * when an action mode is active. + */ + private class ActionModeStatusGuardHack { + private Field _fadeAnimField; + private Field _actionModeViewField; + + @ColorInt + private final int _statusBarColor; + + private ActionModeStatusGuardHack() { + _statusBarColor = getWindow().getStatusBarColor(); + + try { + _fadeAnimField = getDelegate().getClass().getDeclaredField("mFadeAnim"); + _fadeAnimField.setAccessible(true); + _actionModeViewField = getDelegate().getClass().getDeclaredField("mActionModeView"); + _actionModeViewField.setAccessible(true); + } catch (NoSuchFieldException ignored) { + } + } + + private void apply(int visibility) { + if (_fadeAnimField == null || _actionModeViewField == null) { + return; + } + + ViewPropertyAnimatorCompat fadeAnim; + ViewGroup actionModeView; + try { + fadeAnim = (ViewPropertyAnimatorCompat) _fadeAnimField.get(getDelegate()); + actionModeView = (ViewGroup) _actionModeViewField.get(getDelegate()); + } catch (IllegalAccessException e) { + return; + } + + if (fadeAnim == null || actionModeView == null) { + return; + } + + fadeAnim.cancel(); + + actionModeView.setVisibility(visibility); + actionModeView.setAlpha(visibility == View.VISIBLE ? 1f : 0f); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + int statusBarColor = visibility == View.VISIBLE + ? ThemeHelper.getThemeColor(com.google.android.material.R.attr.colorSurfaceContainer, getTheme()) + : _statusBarColor; + getWindow().setStatusBarColor(statusBarColor); + } + } + } + /** * Reports whether this Activity instance has become an orphan. This can happen if * the vault was killed/locked by an external trigger while the Activity was still open. diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java index 685aa812..b64b1586 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java @@ -2,7 +2,6 @@ package com.beemdevelopment.aegis.ui; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.Bundle; import android.text.InputType; import android.view.KeyEvent; @@ -20,11 +19,9 @@ import android.widget.Toast; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.biometric.BiometricPrompt; import com.beemdevelopment.aegis.R; -import com.beemdevelopment.aegis.ThemeMap; import com.beemdevelopment.aegis.crypto.KeyStoreHandle; import com.beemdevelopment.aegis.crypto.KeyStoreHandleException; import com.beemdevelopment.aegis.crypto.MasterKey; @@ -43,6 +40,7 @@ import com.beemdevelopment.aegis.vault.slots.Slot; import com.beemdevelopment.aegis.vault.slots.SlotException; import com.beemdevelopment.aegis.vault.slots.SlotIntegrityException; import com.beemdevelopment.aegis.vault.slots.SlotList; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import java.util.List; @@ -163,10 +161,11 @@ public class AuthActivity extends AegisActivity { biometricsButton.setOnClickListener(v -> { if (_prefs.isPasswordReminderNeeded()) { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(getString(R.string.password_reminder_dialog_title)) .setMessage(getString(R.string.password_reminder_dialog_message)) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, (dialog1, which) -> { showBiometricPrompt(); }) @@ -183,11 +182,6 @@ public class AuthActivity extends AegisActivity { outState.putBoolean("inhibitBioPrompt", _inhibitBioPrompt); } - @Override - protected void onSetTheme() { - setTheme(ThemeMap.NO_ACTION_BAR); - } - private void selectPassword() { _textPassword.selectAll(); @@ -240,9 +234,6 @@ public class AuthActivity extends AegisActivity { PopupWindow popup = new PopupWindow(popupLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); popup.setFocusable(false); popup.setOutsideTouchable(true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ - popup.setElevation(5.0f); - } _textPassword.post(() -> { if (isFinishing()) { return; @@ -302,10 +293,11 @@ public class AuthActivity extends AegisActivity { } private void onInvalidPassword() { - Dialogs.showSecureDialog(new AlertDialog.Builder(AuthActivity.this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(AuthActivity.this, R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(getString(R.string.unlock_vault_error)) .setMessage(getString(R.string.unlock_vault_error_description)) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, (dialog, which) -> selectPassword()) .create()); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java index 91648b42..f9472c58 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java @@ -26,7 +26,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AlertDialog; import com.amulyakhare.textdrawable.TextDrawable; import com.avito.android.krop.KropView; @@ -68,6 +67,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; @@ -164,7 +164,7 @@ public class EditEntryActivity extends AegisActivity { ActionBar bar = getSupportActionBar(); if (bar != null) { - bar.setHomeAsUpIndicator(R.drawable.ic_close); + bar.setHomeAsUpIndicator(R.drawable.ic_outline_close_24); bar.setDisplayHomeAsUpEnabled(true); } @@ -473,7 +473,7 @@ public class EditEntryActivity extends AegisActivity { } else if (itemId == R.id.action_edit_icon) { startIconSelection(); } else if (itemId == R.id.action_reset_usage_count) { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this) .setTitle(R.string.action_reset_usage_count) .setMessage(R.string.action_reset_usage_count_dialog) .setPositiveButton(android.R.string.yes, (dialog, which) -> resetUsageCount()) @@ -754,9 +754,10 @@ public class EditEntryActivity extends AegisActivity { } private void onSaveError(String msg) { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(getString(R.string.saving_profile_error)) .setMessage(msg) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, null) .create()); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java index 2333f0cb..eb202f6d 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/GroupManagerActivity.java @@ -7,7 +7,6 @@ import android.view.View; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -15,6 +14,7 @@ import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.views.GroupAdapter; import com.beemdevelopment.aegis.vault.VaultGroup; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import java.util.ArrayList; import java.util.HashSet; @@ -84,9 +84,10 @@ public class GroupManagerActivity extends AegisActivity implements GroupAdapter. @Override public void onRemoveGroup(VaultGroup group) { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.remove_group) .setMessage(R.string.remove_group_description) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { _removedGroups.add(group.getUUID()); _adapter.removeGroup(group); @@ -98,9 +99,10 @@ public class GroupManagerActivity extends AegisActivity implements GroupAdapter. } public void onRemoveUnusedGroups() { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.remove_unused_groups) .setMessage(R.string.remove_unused_groups_description) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { Set unusedGroups = new HashSet<>(_vaultManager.getVault().getGroups()); unusedGroups.removeAll(_vaultManager.getVault().getUsedGroups()); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java index 93a6fee9..54cf675e 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/ImportEntriesActivity.java @@ -11,7 +11,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -28,6 +27,7 @@ import com.beemdevelopment.aegis.util.UUIDMap; import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.VaultGroup; import com.beemdevelopment.aegis.vault.VaultRepository; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; @@ -62,7 +62,7 @@ public class ImportEntriesActivity extends AegisActivity { _view = findViewById(R.id.importEntriesRootView); ActionBar bar = getSupportActionBar(); - bar.setHomeAsUpIndicator(R.drawable.ic_close); + bar.setHomeAsUpIndicator(R.drawable.ic_outline_close_24); bar.setDisplayHomeAsUpEnabled(true); _adapter = new ImportEntriesAdapter(); @@ -101,10 +101,11 @@ public class ImportEntriesActivity extends AegisActivity { if (importer.isInstalledAppVersionSupported()) { startImportApp(importer); } else { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.warning) .setMessage(getString(R.string.app_version_error, importerDef.getName())) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(R.string.yes, (dialog1, which) -> { startImportApp(importer); }) @@ -215,7 +216,7 @@ public class ImportEntriesActivity extends AegisActivity { List errors = result.getErrors(); if (errors.size() > 0) { String message = getResources().getQuantityString(R.plurals.import_error_dialog, errors.size(), errors.size()); - Dialogs.showMultiErrorDialog(this, R.string.import_error_title, message, errors, null); + Dialogs.showMultiExceptionDialog(this, R.string.import_error_title, message, errors, null); } findDuplicates(importEntries); @@ -296,7 +297,7 @@ public class ImportEntriesActivity extends AegisActivity { assignIconIntent.putExtra("entries", assignIconEntriesIds); - Dialogs.showSecureDialog(new AlertDialog.Builder(this) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this) .setTitle(R.string.import_assign_icons_dialog_title) .setMessage(R.string.import_assign_icons_dialog_text) .setPositiveButton(android.R.string.yes, (dialog, which) -> { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java index 8ab26fe8..701d37b5 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/IntroActivity.java @@ -13,7 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.beemdevelopment.aegis.R; -import com.beemdevelopment.aegis.ThemeMap; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.intro.IntroBaseActivity; import com.beemdevelopment.aegis.ui.intro.SlideFragment; @@ -40,11 +39,6 @@ public class IntroActivity extends IntroBaseActivity { addSlide(DoneSlide.class); } - @Override - protected void onSetTheme() { - setTheme(ThemeMap.NO_ACTION_BAR); - } - @Override protected boolean onBeforeSlideChanged(Class oldSlide, @NonNull Class newSlide) { // hide the keyboard before every slide change diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index b68ef168..4654df0d 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -25,8 +25,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.CheckBox; -import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; import androidx.activity.OnBackPressedCallback; @@ -37,8 +35,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ActionMode; import androidx.appcompat.widget.SearchView; -import com.beemdevelopment.aegis.CopyBehavior; import com.beemdevelopment.aegis.AccountNamePosition; +import com.beemdevelopment.aegis.CopyBehavior; import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.SortCategory; @@ -51,11 +49,13 @@ import com.beemdevelopment.aegis.otp.OtpInfoException; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.fragments.preferences.BackupsPreferencesFragment; import com.beemdevelopment.aegis.ui.fragments.preferences.PreferencesFragment; +import com.beemdevelopment.aegis.ui.models.ErrorCardInfo; import com.beemdevelopment.aegis.ui.tasks.QrDecodeTask; import com.beemdevelopment.aegis.ui.views.EntryListView; import com.beemdevelopment.aegis.util.TimeUtils; import com.beemdevelopment.aegis.vault.VaultEntry; import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.common.base.Strings; @@ -87,8 +87,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene private Menu _menu; private SearchView _searchView; private EntryListView _entryListView; - private LinearLayout _btnErrorBar; - private TextView _textErrorBar; private FabScrollHelper _fabScrollHelper; @@ -223,9 +221,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene Dialogs.showSecureDialog(dialog); }); - _btnErrorBar = findViewById(R.id.btn_error_bar); - _textErrorBar = findViewById(R.id.text_error_bar); - _fabScrollHelper = new FabScrollHelper(fab); _selectedEntries = new ArrayList<>(); } @@ -458,7 +453,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene boolean isSingleBatch = GoogleAuthInfo.Export.isSingleBatch(googleAuthExports); if (!isSingleBatch && errors.size() > 0) { errors.add(getString(R.string.unrelated_google_auth_batches_error)); - Dialogs.showMultiMessageDialog(this, R.string.import_error_title, getString(R.string.no_tokens_can_be_imported), errors, null); + Dialogs.showMultiErrorDialog(this, R.string.import_error_title, getString(R.string.no_tokens_can_be_imported), errors, null); return; } else if (!isSingleBatch) { Dialogs.showErrorDialog(this, R.string.import_google_auth_failure, getString(R.string.unrelated_google_auth_batches_error)); @@ -473,7 +468,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene } if ((errors.size() > 0 && results.size() > 1) || errors.size() > 1) { - Dialogs.showMultiMessageDialog(this, R.string.import_error_title, getString(R.string.unable_to_read_qrcode_files, uris.size() - errors.size(), uris.size()), errors, dialogDismissHandler); + Dialogs.showMultiErrorDialog(this, R.string.import_error_title, getString(R.string.unable_to_read_qrcode_files, uris.size() - errors.size(), uris.size()), errors, dialogDismissHandler); } else if (errors.size() > 0) { Dialogs.showErrorDialog(this, getString(R.string.unable_to_read_qrcode_file, results.get(0).getFileName()), errors.get(0), dialogDismissHandler); } else { @@ -691,7 +686,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene handleIncomingIntent(); updateLockIcon(); doShortcutActions(); - updateErrorBar(); + updateErrorCard(); } private void deleteEntries(List entries) { @@ -851,49 +846,49 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene } } - private void updateErrorBar() { - Preferences.BackupResult backupRes = _prefs.getErroredBackupResult(); - if (backupRes != null) { - _textErrorBar.setText(R.string.backup_error_bar_message); - _btnErrorBar.setOnClickListener(view -> { - Dialogs.showBackupErrorDialog(this, backupRes, (dialog, which) -> { - startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups"); - }); - }); - _btnErrorBar.setVisibility(View.VISIBLE); - } else if (_prefs.isBackupsReminderNeeded() && _prefs.isBackupReminderEnabled()) { - Date date = _prefs.getLatestBackupOrExportTime(); - if (date != null) { - _textErrorBar.setText(getString(R.string.backup_reminder_bar_message_with_latest, TimeUtils.getElapsedSince(this, date))); - } else { - _textErrorBar.setText(R.string.backup_reminder_bar_message); - } - _btnErrorBar.setOnClickListener(view -> { - Dialogs.showSecureDialog(new AlertDialog.Builder(this) - .setTitle(R.string.backup_reminder_bar_dialog_title) - .setMessage(R.string.backup_reminder_bar_dialog_summary) - .setPositiveButton(R.string.backup_reminder_bar_dialog_accept, (dialog, whichButton) -> { - startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups"); - }) - .setNegativeButton(android.R.string.cancel, null) - .create()); - }); - _btnErrorBar.setVisibility(View.VISIBLE); - } else if (_prefs.isPlaintextBackupWarningNeeded()) { - _textErrorBar.setText(R.string.backup_plaintext_export_warning); - _btnErrorBar.setOnClickListener(view -> showPlaintextExportWarningOptions()); - _btnErrorBar.setVisibility(View.VISIBLE); - } else { - _btnErrorBar.setVisibility(View.GONE); - } - } + private void updateErrorCard() { + ErrorCardInfo info = null; + + Preferences.BackupResult backupRes = _prefs.getErroredBackupResult(); + if (backupRes != null) { + info = new ErrorCardInfo(getString(R.string.backup_error_bar_message), view -> { + Dialogs.showBackupErrorDialog(this, backupRes, (dialog, which) -> { + startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups"); + }); + }); + } else if (_prefs.isBackupsReminderNeeded() && _prefs.isBackupReminderEnabled()) { + String text; + Date date = _prefs.getLatestBackupOrExportTime(); + if (date != null) { + text = getString(R.string.backup_reminder_bar_message_with_latest, TimeUtils.getElapsedSince(this, date)); + } else { + text = getString(R.string.backup_reminder_bar_message); + } + info = new ErrorCardInfo(text, view -> { + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Error) + .setTitle(R.string.backup_reminder_bar_dialog_title) + .setMessage(R.string.backup_reminder_bar_dialog_summary) + .setIconAttribute(android.R.attr.alertDialogIcon) + .setPositiveButton(R.string.backup_reminder_bar_dialog_accept, (dialog, whichButton) -> { + startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups"); + }) + .setNegativeButton(android.R.string.cancel, null) + .create()); + }); + } else if (_prefs.isPlaintextBackupWarningNeeded()) { + info = new ErrorCardInfo(getString(R.string.backup_plaintext_export_warning), view -> showPlaintextExportWarningOptions()); + } + + _entryListView.setErrorCardInfo(info); + } private void showPlaintextExportWarningOptions() { View view = LayoutInflater.from(this).inflate(R.layout.dialog_plaintext_warning, null); - AlertDialog dialog = new AlertDialog.Builder(this) + AlertDialog dialog = new MaterialAlertDialogBuilder(this, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.backup_plaintext_export_warning) .setView(view) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, null) .setNegativeButton(android.R.string.cancel, null) .create(); @@ -910,7 +905,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene _prefs.setIsPlaintextBackupWarningDisabled(checkBox.isChecked()); _prefs.setIsPlaintextBackupWarningNeeded(false); - updateErrorBar(); + updateErrorCard(); }); }); @@ -926,8 +921,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene setFavoriteMenuItemVisiblity(); setIsMultipleSelected(_selectedEntries.size() > 1); } - - return; } } @@ -957,14 +950,14 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene if (_selectedEntries.size() == 1){ if (_selectedEntries.get(0).isFavorite()) { - toggleFavoriteMenuItem.setIcon(R.drawable.ic_set_favorite); + toggleFavoriteMenuItem.setIcon(R.drawable.ic_filled_star_24); toggleFavoriteMenuItem.setTitle(R.string.unfavorite); } else { - toggleFavoriteMenuItem.setIcon(R.drawable.ic_unset_favorite); + toggleFavoriteMenuItem.setIcon(R.drawable.ic_outline_star_24); toggleFavoriteMenuItem.setTitle(R.string.favorite); } } else { - toggleFavoriteMenuItem.setIcon(R.drawable.ic_unset_favorite); + toggleFavoriteMenuItem.setIcon(R.drawable.ic_outline_star_24); toggleFavoriteMenuItem.setTitle(String.format("%s / %s", getString(R.string.favorite), getString(R.string.unfavorite))); } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java index cabf338c..0bcccc28 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesActivity.java @@ -16,6 +16,7 @@ import com.beemdevelopment.aegis.ui.fragments.preferences.PreferencesFragment; public class PreferencesActivity extends AegisActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { private Fragment _fragment; + private CharSequence _prefTitle; @Override protected void onCreate(Bundle savedInstanceState) { @@ -48,6 +49,10 @@ public class PreferencesActivity extends AegisActivity implements } } else { _fragment = getSupportFragmentManager().findFragmentById(R.id.content); + _prefTitle = savedInstanceState.getCharSequence("prefTitle"); + if (_prefTitle != null) { + setTitle(_prefTitle); + } } } @@ -69,6 +74,7 @@ public class PreferencesActivity extends AegisActivity implements // this is done so we don't lose anything if the fragment calls recreate on this activity outState.putParcelable("result", ((PreferencesFragment) _fragment).getResult()); } + outState.putCharSequence("prefTitle", _prefTitle); super.onSaveInstanceState(outState); } @@ -90,7 +96,8 @@ public class PreferencesActivity extends AegisActivity implements _fragment.setTargetFragment(caller, 0); showFragment(_fragment); - setTitle(pref.getTitle()); + _prefTitle = pref.getTitle(); + setTitle(_prefTitle); return true; } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java index c5762bbd..7c5ecbd0 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java @@ -87,6 +87,11 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis }, ContextCompat.getMainExecutor(this)); } + @Override + protected void onSetTheme() { + setTheme(ThemeMap.FULLSCREEN); + } + @Override protected void onDestroy() { if (_executor != null) { @@ -95,11 +100,6 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis super.onDestroy(); } - @Override - protected void onSetTheme() { - setTheme(ThemeMap.FULLSCREEN); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { _menu = menu; @@ -142,10 +142,10 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis if (dual) { switch (_currentLens) { case CameraSelector.LENS_FACING_BACK: - item.setIcon(R.drawable.ic_camera_front_24dp); + item.setIcon(R.drawable.ic_outline_camera_front_24); break; case CameraSelector.LENS_FACING_FRONT: - item.setIcon(R.drawable.ic_camera_rear_24dp); + item.setIcon(R.drawable.ic_outline_camera_rear_24); break; } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java b/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java index 8e0bbb51..b1156ee8 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java @@ -40,6 +40,7 @@ import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.slots.PasswordSlot; import com.beemdevelopment.aegis.vault.slots.Slot; import com.beemdevelopment.aegis.vault.slots.SlotException; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; import com.nulabinc.zxcvbn.Strength; @@ -87,9 +88,10 @@ public class Dialogs { } textMessage.setText(message); - showSecureDialog(new AlertDialog.Builder(context) + showSecureDialog(new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(title) .setView(view) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.yes, onDelete) .setNegativeButton(android.R.string.no, null) .create()); @@ -108,9 +110,10 @@ public class Dialogs { } public static void showDiscardDialog(Context context, DialogInterface.OnClickListener onSave, DialogInterface.OnClickListener onDiscard) { - showSecureDialog(new AlertDialog.Builder(context) + showSecureDialog(new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(context.getString(R.string.discard_changes)) .setMessage(context.getString(R.string.discard_changes_description)) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(R.string.save, onSave) .setNegativeButton(R.string.discard, onDiscard) .create()); @@ -138,7 +141,7 @@ public class Dialogs { } }); - AlertDialog dialog = new AlertDialog.Builder(activity) + AlertDialog dialog = new MaterialAlertDialogBuilder(activity) .setTitle(R.string.set_password) .setView(view) .setPositiveButton(android.R.string.ok, null) @@ -209,7 +212,7 @@ public class Dialogs { } inputLayout.setHint(hintId); - AlertDialog.Builder builder = new AlertDialog.Builder(context) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context) .setTitle(titleId) .setView(view) .setPositiveButton(android.R.string.ok, null); @@ -272,7 +275,7 @@ public class Dialogs { CheckBox checkBox = view.findViewById(R.id.checkbox); checkBox.setText(checkboxMessageId); - AlertDialog.Builder builder = new AlertDialog.Builder(context) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context) .setTitle(titleId) .setView(view) .setNegativeButton(R.string.no, (dialog1, which) -> @@ -306,7 +309,7 @@ public class Dialogs { numberPicker.setValue(currentValue); numberPicker.setWrapSelectorWheel(true); - AlertDialog dialog = new AlertDialog.Builder(context) + AlertDialog dialog = new MaterialAlertDialogBuilder(context) .setTitle(R.string.set_number) .setView(view) .setPositiveButton(android.R.string.ok, (dialog1, which) -> @@ -331,7 +334,7 @@ public class Dialogs { numberPicker.setValue(currentVersionCount / 5 - 1); numberPicker.setWrapSelectorWheel(false); - AlertDialog dialog = new AlertDialog.Builder(context) + AlertDialog dialog = new MaterialAlertDialogBuilder(context) .setTitle(R.string.set_number) .setView(view) .setPositiveButton(android.R.string.ok, (dialog1, which) -> @@ -372,10 +375,11 @@ public class Dialogs { TextView textMessage = view.findViewById(R.id.error_message); textMessage.setText(message); - AlertDialog dialog = new AlertDialog.Builder(context) + AlertDialog dialog = new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(R.string.error_occurred) .setView(view) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, (dialog1, which) -> { if (listener != null) { listener.onClick(dialog1, which); @@ -412,34 +416,35 @@ public class Dialogs { Dialogs.showErrorDialog(context, message, backupRes.getError(), listener); } - public static void showMultiMessageDialog( + public static void showMultiErrorDialog( Context context, @StringRes int title, String message, List messages, DialogInterface.OnClickListener listener) { - Dialogs.showSecureDialog(new AlertDialog.Builder(context) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(title) .setMessage(message) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, (dialog, which) -> { if (listener != null) { listener.onClick(dialog, which); } }) .setNeutralButton(context.getString(R.string.details), (dialog, which) -> { - showDetailedMultiMessageDialog(context, title, messages, listener); + showDetailedMultiErrorDialog(context, title, messages, listener); }) .create()); } - public static void showMultiErrorDialog( + public static void showMultiExceptionDialog( Context context, @StringRes int title, String message, List errors, DialogInterface.OnClickListener listener) { List messages = new ArrayList<>(); for (Throwable e : errors) { messages.add(e.toString()); } - showMultiMessageDialog(context, title, message, messages, listener); + showMultiErrorDialog(context, title, message, messages, listener); } - private static void showDetailedMultiMessageDialog( + private static void showDetailedMultiErrorDialog( Context context, @StringRes int title, List messages, DialogInterface.OnClickListener listener) { SpannableStringBuilder builder = new SpannableStringBuilder(); for (CharSequence message : messages) { @@ -447,10 +452,11 @@ public class Dialogs { builder.append("\n\n"); } - AlertDialog dialog = new AlertDialog.Builder(context) + AlertDialog dialog = new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(title) .setMessage(builder) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.ok, (dialog1, which) -> { if (listener != null) { listener.onClick(dialog1, which); @@ -477,10 +483,11 @@ public class Dialogs { View view = LayoutInflater.from(context).inflate(R.layout.dialog_time_sync, null); CheckBox checkBox = view.findViewById(R.id.check_warning_disable); - showSecureDialog(new AlertDialog.Builder(context) + showSecureDialog(new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.time_sync_warning_title) .setView(view) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(R.string.yes, (dialog, which) -> { if (checkBox.isChecked()) { prefs.setIsTimeSyncWarningEnabled(false); @@ -515,7 +522,7 @@ public class Dialogs { setImporterHelpText(helpText, importers.get(position), isDirect); }); - Dialogs.showSecureDialog(new AlertDialog.Builder(context) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(context) .setTitle(R.string.choose_application) .setView(view) .setPositiveButton(android.R.string.ok, (dialog1, which) -> { @@ -536,11 +543,12 @@ public class Dialogs { errorDetails.append("\n\n"); } - AlertDialog.Builder builder = new AlertDialog.Builder(context) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.partial_google_auth_import) .setMessage(context.getString(R.string.partial_google_auth_import_warning, missingIndexesAsString)) .setView(view) .setCancelable(false) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(context.getString(R.string.import_partial_export_anyway, entries), (dialog, which) -> { dismissHandler.onClick(dialog, which); }) diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java b/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java index 930da65e..cf984aea 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/SimpleWebViewDialog.java @@ -18,6 +18,7 @@ import androidx.fragment.app.DialogFragment; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.helpers.ThemeHelper; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.common.io.CharStreams; import java.io.IOException; @@ -44,14 +45,14 @@ public abstract class SimpleWebViewDialog extends DialogFragment { view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_web_view, null); } catch (InflateException e) { e.printStackTrace(); - return new AlertDialog.Builder(requireContext()) + return new MaterialAlertDialogBuilder(requireContext()) .setTitle(android.R.string.dialog_alert_title) .setMessage(getString(R.string.webview_error)) .setPositiveButton(android.R.string.ok, null) .show(); } - AlertDialog dialog = new AlertDialog.Builder(requireContext()) + AlertDialog dialog = new MaterialAlertDialogBuilder(requireContext()) .setTitle(_title) .setView(view) .setPositiveButton(android.R.string.ok, null) @@ -69,12 +70,11 @@ public abstract class SimpleWebViewDialog extends DialogFragment { } protected String getBackgroundColor() { - int backgroundColorResource = _theme == Theme.AMOLED ? R.attr.cardBackgroundFocused : R.attr.cardBackground; - return colorToCSS(ThemeHelper.getThemeColor(backgroundColorResource, requireContext().getTheme())); + return colorToCSS(ThemeHelper.getThemeColor(com.google.android.material.R.attr.colorSurfaceContainerHigh, requireContext().getTheme())); } protected String getTextColor() { - return colorToCSS(0xFFFFFF & ThemeHelper.getThemeColor(R.attr.primaryText, requireContext().getTheme())); + return colorToCSS(0xFFFFFF & ThemeHelper.getThemeColor(com.google.android.material.R.attr.colorOnSurface, requireContext().getTheme())); } @SuppressLint("DefaultLocale") diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java index 3c99f55b..c8f324c7 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/AppearancePreferencesFragment.java @@ -8,11 +8,17 @@ import androidx.appcompat.app.AlertDialog; import androidx.preference.Preference; import com.beemdevelopment.aegis.AccountNamePosition; +import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.Theme; import com.beemdevelopment.aegis.ViewMode; import com.beemdevelopment.aegis.ui.GroupManagerActivity; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; +import com.google.android.material.color.DynamicColors; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import java.util.Arrays; +import java.util.List; public class AppearancePreferencesFragment extends PreferencesFragment { private Preference _groupsPreference; @@ -33,7 +39,7 @@ public class AppearancePreferencesFragment extends PreferencesFragment { _resetUsageCountPreference = requirePreference("pref_reset_usage_count"); _resetUsageCountPreference.setOnPreferenceClickListener(preference -> { - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.preference_reset_usage_count) .setMessage(R.string.preference_reset_usage_count_dialog) .setPositiveButton(android.R.string.yes, (dialog, which) -> _prefs.clearUsageCount()) @@ -48,7 +54,7 @@ public class AppearancePreferencesFragment extends PreferencesFragment { darkModePreference.setOnPreferenceClickListener(preference -> { int currentTheme1 = _prefs.getCurrentTheme().ordinal(); - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.choose_theme) .setSingleChoiceItems(R.array.theme_titles, currentTheme1, (dialog, which) -> { int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); @@ -65,11 +71,36 @@ public class AppearancePreferencesFragment extends PreferencesFragment { return true; }); + Preference dynamicColorsPreference = requirePreference("pref_dynamic_colors"); + dynamicColorsPreference.setEnabled(DynamicColors.isDynamicColorAvailable()); + dynamicColorsPreference.setOnPreferenceChangeListener((preference, newValue) -> { + getResult().putExtra("needsRecreate", true); + requireActivity().recreate(); + return true; + }); + Preference langPreference = requirePreference("pref_lang"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - langPreference.setOnPreferenceChangeListener((preference, newValue) -> { - getResult().putExtra("needsRecreate", true); - requireActivity().recreate(); + String[] langs = getResources().getStringArray(R.array.pref_lang_values); + String[] langNames = getResources().getStringArray(R.array.pref_lang_entries); + List langList = Arrays.asList(langs); + int curLangIndex = langList.contains(_prefs.getLanguage()) ? langList.indexOf(_prefs.getLanguage()) : 0; + langPreference.setSummary(langNames[curLangIndex]); + langPreference.setOnPreferenceClickListener(preference -> { + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.pref_lang_title) + .setSingleChoiceItems(langNames, curLangIndex, (dialog, which) -> { + int newLangIndex = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); + _prefs.setLanguage(langs[newLangIndex]); + langPreference.setSummary(langNames[newLangIndex]); + + dialog.dismiss(); + + getResult().putExtra("needsRecreate", true); + requireActivity().recreate(); + }) + .setNegativeButton(android.R.string.cancel, null) + .create()); return true; }); } else { @@ -83,7 +114,7 @@ public class AppearancePreferencesFragment extends PreferencesFragment { viewModePreference.setOnPreferenceClickListener(preference -> { int currentViewMode1 = _prefs.getCurrentViewMode().ordinal(); - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.choose_view_mode) .setSingleChoiceItems(R.array.view_mode_titles, currentViewMode1, (dialog, which) -> { int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); @@ -99,9 +130,22 @@ public class AppearancePreferencesFragment extends PreferencesFragment { return true; }); + String[] codeGroupings = getResources().getStringArray(R.array.pref_code_groupings_values); + String[] codeGroupingNames = getResources().getStringArray(R.array.pref_code_groupings); + int currentCodeGroupingIndex = Arrays.asList(codeGroupings).indexOf(_prefs.getCodeGroupSize().name()); Preference codeDigitGroupingPreference = requirePreference("pref_code_group_size_string"); - codeDigitGroupingPreference.setOnPreferenceChangeListener((preference, newValue) -> { - getResult().putExtra("needsRefresh", true); + codeDigitGroupingPreference.setOnPreferenceClickListener(preference -> { + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.pref_code_group_size_title) + .setSingleChoiceItems(codeGroupingNames, currentCodeGroupingIndex, (dialog, which) -> { + int newCodeGroupingIndex = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); + _prefs.setCodeGroupSize(Preferences.CodeGrouping.valueOf(codeGroupings[newCodeGroupingIndex])); + + dialog.dismiss(); + getResult().putExtra("needsRefresh", true); + }) + .setNegativeButton(android.R.string.cancel, null) + .create()); return true; }); @@ -117,7 +161,7 @@ public class AppearancePreferencesFragment extends PreferencesFragment { _currentAccountNamePositionPreference.setOnPreferenceClickListener(preference -> { int currentAccountNamePosition1 = _prefs.getAccountNamePosition().ordinal(); - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) .setTitle(getString(R.string.choose_account_name_position)) .setSingleChoiceItems(R.array.account_name_position_titles, currentAccountNamePosition1, (dialog, which) -> { int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java index 2615e711..affe3e6c 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BackupsPreferencesFragment.java @@ -19,6 +19,7 @@ import androidx.preference.SwitchPreferenceCompat; import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; +import com.beemdevelopment.aegis.helpers.ThemeHelper; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.vault.VaultRepositoryException; @@ -195,9 +196,9 @@ public class BackupsPreferencesFragment extends PreferencesFragment { // TODO: Find out why setting the tint of the icon doesn't work if (backupFailed) { - pref.setIcon(R.drawable.ic_info_outline_black_24dp); + pref.setIcon(R.drawable.ic_outline_error_24); } else if (res != null) { - pref.setIcon(R.drawable.ic_check_black_24dp); + pref.setIcon(R.drawable.ic_outline_check_24); } else { pref.setIcon(null); } @@ -205,21 +206,20 @@ public class BackupsPreferencesFragment extends PreferencesFragment { private CharSequence getBackupStatusMessage(@Nullable Preferences.BackupResult res) { String message; - int color = R.color.warning_color; + int colorAttr = com.google.android.material.R.attr.colorError; if (res == null) { message = getString(R.string.backup_status_none); } else if (res.isSuccessful()) { - color = R.color.success_color; + colorAttr = R.attr.colorSuccess; message = getString(R.string.backup_status_success, res.getElapsedSince(requireContext())); } else { message = getString(R.string.backup_status_failed, res.getElapsedSince(requireContext())); } + int color = ThemeHelper.getThemeColor(colorAttr, requireContext().getTheme()); Spannable spannable = new SpannableString(message); - spannable.setSpan(new ForegroundColorSpan(getResources().getColor(color)), 0, message.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - if (color == R.color.warning_color) { - spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, message.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } + spannable.setSpan(new ForegroundColorSpan(color), 0, message.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, message.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spannable; } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java index 47646418..278f53dd 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/BehaviorPreferencesFragment.java @@ -8,6 +8,7 @@ import androidx.preference.Preference; import com.beemdevelopment.aegis.CopyBehavior; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; public class BehaviorPreferencesFragment extends PreferencesFragment { private Preference _entryPausePreference; @@ -23,7 +24,7 @@ public class BehaviorPreferencesFragment extends PreferencesFragment { copyBehaviorPreference.setOnPreferenceClickListener(preference -> { int currentCopyBehavior1 = _prefs.getCopyBehavior().ordinal(); - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext()) .setTitle(getString(R.string.choose_copy_behavior)) .setSingleChoiceItems(R.array.copy_behavior_titles, currentCopyBehavior1, (dialog, which) -> { int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java index cb30d832..863ddbf0 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/IconPacksManagerFragment.java @@ -14,7 +14,6 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -30,6 +29,7 @@ import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.tasks.ImportIconPackTask; import com.beemdevelopment.aegis.ui.views.IconPackAdapter; import com.beemdevelopment.aegis.vault.VaultManager; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import javax.inject.Inject; @@ -102,9 +102,10 @@ public class IconPacksManagerFragment extends Fragment implements IconPackAdapte @Override public void onRemoveIconPack(IconPack pack) { - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.remove_icon_pack) .setMessage(R.string.remove_icon_pack_description) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { try { _iconPackManager.removeIconPack(pack); @@ -124,9 +125,10 @@ public class IconPacksManagerFragment extends Fragment implements IconPackAdapte ImportIconPackTask task = new ImportIconPackTask(requireContext(), result -> { Exception e = result.getException(); if (e instanceof IconPackExistsException) { - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(R.string.error_occurred) .setMessage(R.string.icon_pack_import_exists_error) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(R.string.yes, (dialog, which) -> { if (removeIconPack(((IconPackExistsException) e).getIconPack())) { importIconPack(uri); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java index cdd810b0..acd8188d 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/ImportExportPreferencesFragment.java @@ -45,6 +45,7 @@ import com.beemdevelopment.aegis.vault.VaultRepository; import com.beemdevelopment.aegis.vault.VaultRepositoryException; import com.beemdevelopment.aegis.vault.slots.PasswordSlot; import com.beemdevelopment.aegis.vault.slots.SlotException; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputLayout; import java.io.File; @@ -202,7 +203,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment { groupsSelection.addItems(groupsArray, false); } - AlertDialog dialog = new AlertDialog.Builder(requireContext()) + AlertDialog dialog = new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.pref_export_summary) .setView(view) .setNeutralButton(R.string.share, null) diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java index f1786017..3ba3d59a 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java @@ -30,6 +30,7 @@ import com.beemdevelopment.aegis.vault.slots.PasswordSlot; import com.beemdevelopment.aegis.vault.slots.Slot; import com.beemdevelopment.aegis.vault.slots.SlotException; import com.beemdevelopment.aegis.vault.slots.SlotList; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import java.util.Arrays; import java.util.List; @@ -91,9 +92,10 @@ public class SecurityPreferencesFragment extends PreferencesFragment { if (!_vaultManager.getVault().isEncryptionEnabled()) { Dialogs.showSetPasswordDialog(requireActivity(), new EnableEncryptionListener()); } else { - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Aegis_AlertDialog_Warning) .setTitle(R.string.disable_encryption) .setMessage(getText(R.string.disable_encryption_description)) + .setIconAttribute(android.R.attr.alertDialogIcon) .setPositiveButton(android.R.string.yes, (dialog, which) -> { try { _vaultManager.disableEncryption(); @@ -169,9 +171,10 @@ public class SecurityPreferencesFragment extends PreferencesFragment { task.execute(getLifecycle(), params); } else { _pinKeyboardPreference.setChecked(false); - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(R.string.pin_keyboard_error) .setMessage(R.string.pin_keyboard_error_description) + .setIconAttribute(android.R.attr.alertDialogIcon) .setCancelable(false) .setPositiveButton(android.R.string.ok, null) .create()); @@ -192,7 +195,7 @@ public class SecurityPreferencesFragment extends PreferencesFragment { checkedItems[i] = _prefs.isAutoLockTypeEnabled(items[i]); } - AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.pref_auto_lock_prompt) .setMultiChoiceItems(textItems, checkedItems, (dialog, index, isChecked) -> checkedItems[index] = isChecked) .setPositiveButton(android.R.string.ok, (dialog, which) -> { @@ -221,7 +224,7 @@ public class SecurityPreferencesFragment extends PreferencesFragment { .map(f -> getString(f.getStringRes())) .toArray(String[]::new); - AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.pref_password_reminder_title) .setSingleChoiceItems(textItems, currFreq.ordinal(), (dialog, which) -> { int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); @@ -459,9 +462,10 @@ public class SecurityPreferencesFragment extends PreferencesFragment { if (result != null) { _pinKeyboardPreference.setChecked(true); } else { - Dialogs.showSecureDialog(new AlertDialog.Builder(requireContext()) + Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Aegis_AlertDialog_Error) .setTitle(R.string.pin_keyboard_error) .setMessage(R.string.invalid_password) + .setIconAttribute(android.R.attr.alertDialogIcon) .setCancelable(false) .setPositiveButton(android.R.string.ok, null) .create()); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java index ce4c89c1..d187e87c 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/intro/IntroBaseActivity.java @@ -2,7 +2,6 @@ package com.beemdevelopment.aegis.ui.intro; import android.os.Bundle; import android.view.View; -import android.widget.ImageButton; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; @@ -16,6 +15,7 @@ import androidx.viewpager2.widget.ViewPager2; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.helpers.AnimationsHelper; import com.beemdevelopment.aegis.ui.AegisActivity; +import com.google.android.material.button.MaterialButton; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -28,8 +28,8 @@ public abstract class IntroBaseActivity extends AegisActivity implements IntroAc private List> _slides; private WeakReference _currentSlide; - private ImageButton _btnPrevious; - private ImageButton _btnNext; + private MaterialButton _btnPrevious; + private MaterialButton _btnNext; private SlideIndicator _slideIndicator; @Override @@ -158,7 +158,7 @@ public abstract class IntroBaseActivity extends AegisActivity implements IntroAc ? View.VISIBLE : View.INVISIBLE); if (pos == _slides.size() - 1) { - _btnNext.setImageResource(R.drawable.circular_button_done); + _btnNext.setIconResource(R.drawable.ic_outline_check_24); } _slideIndicator.setSlideCount(_slides.size()); _slideIndicator.setCurrentSlide(pos); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/models/ErrorCardInfo.java b/app/src/main/java/com/beemdevelopment/aegis/ui/models/ErrorCardInfo.java new file mode 100644 index 00000000..c6385e56 --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/models/ErrorCardInfo.java @@ -0,0 +1,21 @@ +package com.beemdevelopment.aegis.ui.models; + +import android.view.View; + +public class ErrorCardInfo { + private final String _message; + private final View.OnClickListener _listener; + + public ErrorCardInfo(String message, View.OnClickListener listener) { + _message = message; + _listener = listener; + } + + public String getMessage() { + return _message; + } + + public View.OnClickListener getListener() { + return _listener; + } +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ProgressDialogTask.java b/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ProgressDialogTask.java index d7d6cf86..ddd9001f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ProgressDialogTask.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ProgressDialogTask.java @@ -1,26 +1,38 @@ package com.beemdevelopment.aegis.ui.tasks; import android.app.Dialog; -import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.os.Process; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; import androidx.annotation.CallSuper; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; +import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; public abstract class ProgressDialogTask extends AsyncTask { - private ProgressDialog _dialog; + private final AlertDialog _dialog; + private final TextView _textProgress; public ProgressDialogTask(Context context, String message) { - _dialog = new ProgressDialog(context); - _dialog.setCancelable(false); - _dialog.setMessage(message); + View view = LayoutInflater.from(context).inflate(R.layout.dialog_progress, null); + _textProgress = view.findViewById(R.id.text_progress); + _textProgress.setText(message); + + _dialog = new MaterialAlertDialogBuilder(context) + .setView(view) + .setCancelable(false) + .create(); + Dialogs.secureDialog(_dialog); } @@ -41,7 +53,7 @@ public abstract class ProgressDialogTask extends AsyncTask extends AsyncTask private Handler _dimHandler; private Handler _doubleTapHandler; private boolean _pauseFocused; + private ErrorCardInfo _errorCardInfo; // keeps track of the EntryHolders that are currently bound private List _holders; @@ -130,8 +132,21 @@ public class EntryAdapter extends RecyclerView.Adapter _pauseFocused = pauseFocused; } - public VaultEntry getEntryAt(int position) { - return _shownEntries.get(position); + public void setErrorCardInfo(ErrorCardInfo info) { + ErrorCardInfo oldInfo = _errorCardInfo; + _errorCardInfo = info; + + if (oldInfo == null && info != null) { + notifyItemInserted(0); + } else if (oldInfo != null && info == null) { + notifyItemRemoved(0); + } else { + notifyItemChanged(0); + } + } + + public VaultEntry getEntryAtPos(int position) { + return _shownEntries.get(translateEntryPosToIndex(position)); } public int addEntry(VaultEntry entry) { @@ -148,17 +163,17 @@ public class EntryAdapter extends RecyclerView.Adapter for (int i = getShownFavoritesCount(); i < _shownEntries.size(); i++) { if (comparator.compare(_shownEntries.get(i), entry) > 0) { _shownEntries.add(i, entry); - notifyItemInserted(i); - position = i; + position = translateEntryIndexToPos(i); + notifyItemInserted(position); break; } } } - if (position < 0){ + if (position < 0) { _shownEntries.add(entry); - position = getItemCount() - 1; + position = translateEntryIndexToPos(getShownEntriesCount() - 1); if (position == 0) { notifyDataSetChanged(); } else { @@ -186,9 +201,12 @@ public class EntryAdapter extends RecyclerView.Adapter _entries.remove(entry); if (_shownEntries.contains(entry)) { - int position = _shownEntries.indexOf(entry); - _shownEntries.remove(position); + int index = _shownEntries.indexOf(entry); + _shownEntries.remove(index); + + int position = translateEntryIndexToPos(index); notifyItemRemoved(position); + updateFooter(); } @@ -213,26 +231,32 @@ public class EntryAdapter extends RecyclerView.Adapter _entries.set(_entries.indexOf(oldEntry), newEntry); if (_shownEntries.contains(oldEntry)) { - int position = _shownEntries.indexOf(oldEntry); + int index = _shownEntries.indexOf(oldEntry); + int position = translateEntryIndexToPos(index); if (isEntryFiltered(newEntry)) { - _shownEntries.remove(position); + _shownEntries.remove(index); notifyItemRemoved(position); } else { - _shownEntries.set(position, newEntry); + _shownEntries.set(index, newEntry); notifyItemChanged(position); } sortShownEntries(); - int newPosition = _shownEntries.indexOf(newEntry); + int newIndex = _shownEntries.indexOf(newEntry); + int newPosition = translateEntryIndexToPos(newIndex); if (newPosition != NO_POSITION && position != newPosition) { notifyItemMoved(position, newPosition); } } else if (!isEntryFiltered(newEntry)) { + // NOTE: This logic is wrong, because sorting is not taken into account. This code + // path is currently never hit though, because it is not possible to edit an entry + // that is not shown. _shownEntries.add(newEntry); int position = getItemCount() - 1; notifyItemInserted(position); } + checkPeriodUniformity(); updateFooter(); } @@ -247,6 +271,36 @@ public class EntryAdapter extends RecyclerView.Adapter return null; } + /** + * Translates the given entry position in the recycler view, to its index in the shown entries list. + */ + public int translateEntryPosToIndex(int position) { + if (position == NO_POSITION) { + return NO_POSITION; + } + + if (isErrorCardShown()) { + position -= 1; + } + + return position; + } + + /** + * Translates the given entry index in the shown entries list, to its position in the recycler view. + */ + private int translateEntryIndexToPos(int index) { + if (index == NO_POSITION) { + return NO_POSITION; + } + + if (isErrorCardShown()) { + index += 1; + } + + return index; + } + private boolean isEntryFiltered(VaultEntry entry) { Set groups = entry.getGroups(); String issuer = entry.getIssuer().toLowerCase(); @@ -366,33 +420,42 @@ public class EntryAdapter extends RecyclerView.Adapter public void onItemDrop(int position) { // moving entries is not allowed when a filter is applied // footer cant be moved, nor can items be moved below it - if (!_groupFilter.isEmpty() || isPositionFooter(position)) { + if (!_groupFilter.isEmpty() || isPositionFooter(position) || isPositionErrorCard(position)) { return; } - _view.onEntryDrop(_shownEntries.get(position)); + int index = translateEntryPosToIndex(position); + _view.onEntryDrop(_shownEntries.get(index)); } @Override public void onItemMove(int firstPosition, int secondPosition) { // moving entries is not allowed when a filter is applied // footer cant be moved, nor can items be moved below it - if (!_groupFilter.isEmpty() || isPositionFooter(firstPosition) || isPositionFooter(secondPosition)) { + if (!_groupFilter.isEmpty() + || isPositionFooter(firstPosition) || isPositionFooter(secondPosition) + || isPositionErrorCard(firstPosition) || isPositionErrorCard(secondPosition)) { return; } // notify the vault first - _view.onEntryMove(_entries.get(firstPosition), _entries.get(secondPosition)); + int firstIndex = translateEntryPosToIndex(firstPosition); + int secondIndex = translateEntryPosToIndex(secondPosition); + _view.onEntryMove(_entries.get(firstIndex), _entries.get(secondIndex)); // then update our end - CollectionUtils.move(_entries, firstPosition, secondPosition); - CollectionUtils.move(_shownEntries, firstPosition, secondPosition); + CollectionUtils.move(_entries, firstIndex, secondIndex); + CollectionUtils.move(_shownEntries, firstIndex, secondIndex); notifyItemMoved(firstPosition, secondPosition); } @Override public int getItemViewType(int position) { + if (isPositionErrorCard(position)) { + return R.layout.card_error; + } + if (isPositionFooter(position)) { return R.layout.card_footer; } @@ -406,7 +469,15 @@ public class EntryAdapter extends RecyclerView.Adapter RecyclerView.ViewHolder holder; View view = inflater.inflate(viewType, parent, false); - holder = viewType == R.layout.card_footer ? new FooterView(view) : new EntryHolder(view); + + if (viewType == R.layout.card_error) { + holder = new ErrorCardHolder(view, _errorCardInfo); + } else if (viewType == R.layout.card_footer) { + holder = new FooterView(view); + } else { + holder = new EntryHolder(view); + } + if (_showIcon && holder instanceof EntryHolder) { _view.setPreloadView(((EntryHolder) holder).getIconView()); } @@ -426,7 +497,8 @@ public class EntryAdapter extends RecyclerView.Adapter public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { if (holder instanceof EntryHolder) { EntryHolder entryHolder = (EntryHolder) holder; - VaultEntry entry = _shownEntries.get(position); + int index = translateEntryPosToIndex(position); + VaultEntry entry = _shownEntries.get(index); boolean hidden = _tapToReveal && entry != _focusedEntry; boolean paused = _pauseFocused && entry == _focusedEntry; @@ -508,12 +580,13 @@ public class EntryAdapter extends RecyclerView.Adapter entryHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - int position = holder.getAdapterPosition(); + int position = holder.getBindingAdapterPosition(); if (_selectedEntries.isEmpty()) { entryHolder.setFocusedAndAnimate(true); } - boolean returnVal = _view.onLongEntryClick(_shownEntries.get(position)); + int index = translateEntryPosToIndex(position); + boolean returnVal = _view.onLongEntryClick(_shownEntries.get(index)); if (_selectedEntries.size() == 0 || isEntryDraggable(entry)) { _view.startDrag(entryHolder); } @@ -748,15 +821,30 @@ public class EntryAdapter extends RecyclerView.Adapter @Override public int getItemCount() { - return getEntriesCount() + 1; + // Always at least one item because of the footer + // Two in case there's also an error card + int baseCount = 1; + if (isErrorCardShown()) { + baseCount++; + } + + return baseCount + getShownEntriesCount(); } - public int getEntriesCount() { + public int getShownEntriesCount() { return _shownEntries.size(); } public boolean isPositionFooter(int position) { - return position == getEntriesCount(); + return position == (getItemCount() - 1); + } + + public boolean isPositionErrorCard(int position) { + return isErrorCardShown() && position == 0; + } + + public boolean isErrorCardShown() { + return _errorCardInfo != null; } private void updateFooter() { @@ -772,7 +860,7 @@ public class EntryAdapter extends RecyclerView.Adapter } public void refresh() { - int entriesShown = getEntriesCount(); + int entriesShown = getShownEntriesCount(); SpannableString entriesShownSpannable = new SpannableString(_footerView.getResources().getQuantityString(R.plurals.entries_shown, entriesShown, entriesShown)); String entriesShownString = String.format("%d", entriesShown); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java index dc3d1f04..7eebe93f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java @@ -1,6 +1,5 @@ package com.beemdevelopment.aegis.ui.views; -import android.graphics.PorterDuff; import android.os.Handler; import android.view.View; import android.view.animation.Animation; @@ -17,7 +16,6 @@ import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.ViewMode; import com.beemdevelopment.aegis.helpers.AnimationsHelper; import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener; -import com.beemdevelopment.aegis.helpers.ThemeHelper; import com.beemdevelopment.aegis.helpers.UiRefresher; import com.beemdevelopment.aegis.otp.HotpInfo; import com.beemdevelopment.aegis.otp.OtpInfo; @@ -28,6 +26,7 @@ import com.beemdevelopment.aegis.otp.YandexInfo; import com.beemdevelopment.aegis.ui.glide.GlideHelper; import com.beemdevelopment.aegis.vault.VaultEntry; import com.bumptech.glide.Glide; +import com.google.android.material.card.MaterialCardView; public class EntryHolder extends RecyclerView.ViewHolder { private static final float DEFAULT_ALPHA = 1.0f; @@ -56,7 +55,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { private boolean _paused; private TotpProgressBar _progressBar; - private View _view; + private MaterialCardView _view; private UiRefresher _refresher; private Handler _animationHandler; @@ -67,8 +66,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { public EntryHolder(final View view) { super(view); - _view = view.findViewById(R.id.rlCardEntry); - + _view = (MaterialCardView) view; _profileName = view.findViewById(R.id.profile_account_name); _profileCode = view.findViewById(R.id.profile_code); _profileIssuer = view.findViewById(R.id.profile_issuer); @@ -84,9 +82,6 @@ public class EntryHolder extends RecyclerView.ViewHolder { _animationHandler = new Handler(); _progressBar = view.findViewById(R.id.progressBar); - int primaryColorId = view.getContext().getResources().getColor(R.color.colorPrimary); - _progressBar.getProgressDrawable().setColorFilter(primaryColorId, PorterDuff.Mode.SRC_IN); - _view.setBackground(_view.getContext().getResources().getDrawable(R.color.card_background)); _scaleIn = AnimationsHelper.loadScaledAnimation(view.getContext(), R.anim.item_scale_in); _scaleOut = AnimationsHelper.loadScaledAnimation(view.getContext(), R.anim.item_scale_out); @@ -229,11 +224,8 @@ public class EntryHolder extends RecyclerView.ViewHolder { public void setFocused(boolean focused) { if (focused) { _selected.setVisibility(View.VISIBLE); - _view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackgroundFocused, _view.getContext().getTheme())); - } else { - _view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackground, _view.getContext().getTheme())); } - _view.setSelected(focused); + _view.setChecked(focused); } public void setFocusedAndAnimate(boolean focused) { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java index 0b0c6974..ab26fe2a 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java @@ -37,6 +37,7 @@ import com.beemdevelopment.aegis.helpers.UiRefresher; import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.glide.GlideHelper; +import com.beemdevelopment.aegis.ui.models.ErrorCardInfo; import com.beemdevelopment.aegis.ui.models.VaultGroupModel; import com.beemdevelopment.aegis.util.UUIDMap; import com.beemdevelopment.aegis.vault.VaultEntry; @@ -131,7 +132,9 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { - if (_viewMode == ViewMode.TILES && position == _adapter.getEntriesCount()) { + if (_viewMode == ViewMode.TILES + && (_adapter.isPositionFooter(position) + || _adapter.isPositionErrorCard(position))) { return 2; } @@ -376,6 +379,10 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { _adapter.setTapToRevealTime(number); } + public void setErrorCardInfo(ErrorCardInfo info) { + _adapter.setErrorCardInfo(info); + } + public void addEntry(VaultEntry entry) { addEntry(entry, false); } @@ -472,7 +479,7 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { } private void addChipTo(ChipGroup chipGroup, VaultGroupModel group) { - Chip chip = (Chip) getLayoutInflater().inflate(R.layout.chip_material, null, false); + Chip chip = (Chip) getLayoutInflater().inflate(R.layout.chip_group_filter, null, false); chip.setText(group.getName()); chip.setCheckable(true); chip.setChecked(_groupFilter != null && _groupFilter.contains(group.getUUID())); @@ -600,7 +607,7 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { } private void updateEmptyState() { - if (_adapter.getEntriesCount() > 0) { + if (_adapter.getShownEntriesCount() > 0) { _recyclerView.setVisibility(View.VISIBLE); _emptyStateView.setVisibility(View.GONE); } else { @@ -636,6 +643,11 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + if (_adapter.isPositionErrorCard(parent.getChildAdapterPosition(view))) { + outRect.top = MetricsHelper.convertDpToPixels(requireContext(), 4); + return; + } + if (_adapter.isPositionFooter(parent.getChildAdapterPosition(view))) { int pixels = MetricsHelper.convertDpToPixels(requireContext(), 20); outRect.top = pixels; @@ -662,41 +674,43 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { return; } - // The footer always has a top and bottom margin - if (_adapter.isPositionFooter(adapterPosition)) { + // The error card and the footer always have a top and bottom margin + if (_adapter.isPositionErrorCard(adapterPosition) + || _adapter.isPositionFooter(adapterPosition)) { outRect.top = _height; outRect.bottom = _height; return; } - // The first entry should have a top margin, but only if the group chip is not shown - if (adapterPosition == 0 && (_groups == null || _groups.isEmpty())) { + int entryIndex = _adapter.translateEntryPosToIndex(adapterPosition); + // The first entry should have a top margin, but only if the group chip is not shown and the error card is not shown + if (entryIndex == 0 && (_groups == null || _groups.isEmpty()) && !_adapter.isErrorCardShown()) { outRect.top = _height; } // Only non-favorite entries have a bottom margin, except for the final favorite entry int totalFavorites = _adapter.getShownFavoritesCount(); if (totalFavorites == 0 - || (adapterPosition < _adapter.getEntriesCount() && !_adapter.getEntryAt(adapterPosition).isFavorite()) - || totalFavorites == adapterPosition + 1) { + || (entryIndex < _adapter.getShownEntriesCount() && !_adapter.getEntryAtPos(adapterPosition).isFavorite()) + || totalFavorites == entryIndex + 1) { outRect.bottom = _height; } if (totalFavorites > 0) { // If this entry is the last favorite entry in the list, it should always have // a bottom margin, regardless of the view mode - if (adapterPosition == totalFavorites - 1) { + if (entryIndex == totalFavorites - 1) { outRect.bottom = _height; } // If this is the first non-favorite entry, it should have a top margin - if (adapterPosition == totalFavorites) { + if (entryIndex == totalFavorites) { outRect.top = _height; } } // The last entry should never have a bottom margin - if (_adapter.getEntriesCount() == adapterPosition + 1) { + if (_adapter.getShownEntriesCount() == entryIndex + 1) { outRect.bottom = 0; } } @@ -734,7 +748,11 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { return Collections.emptyList(); } - VaultEntry entry = _adapter.getEntryAt(position); + if (_adapter.getItemViewType(position) == R.layout.card_error) { + return Collections.emptyList(); + } + + VaultEntry entry = _adapter.getEntryAtPos(position); if (!entry.hasIcon()) { return Collections.emptyList(); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/ErrorCardHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/ErrorCardHolder.java new file mode 100644 index 00000000..649212ba --- /dev/null +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/ErrorCardHolder.java @@ -0,0 +1,23 @@ +package com.beemdevelopment.aegis.ui.views; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.beemdevelopment.aegis.R; +import com.beemdevelopment.aegis.ui.models.ErrorCardInfo; +import com.google.android.material.card.MaterialCardView; + +public class ErrorCardHolder extends RecyclerView.ViewHolder { + public ErrorCardHolder(@NonNull View itemView, ErrorCardInfo info) { + super(itemView); + + TextView errorTextView = itemView.findViewById(R.id.text_error_bar); + errorTextView.setText(info.getMessage()); + + MaterialCardView errorCard = itemView.findViewById(R.id.card_error); + errorCard.setOnClickListener(info.getListener()); + } +} diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/IconHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/IconHolder.java index 70f7de26..c1ba540e 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/IconHolder.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/IconHolder.java @@ -39,8 +39,8 @@ public class IconHolder extends RecyclerView.ViewHolder { public void loadIcon(Context context) { if (_isCustom) { - int tint = ThemeHelper.getThemeColor(R.attr.iconColorPrimary, context.getTheme()); - GlideHelper.loadResource(Glide.with(context), R.drawable.ic_plus_black_24dp, tint, _imageView); + int tint = ThemeHelper.getThemeColor(com.google.android.material.R.attr.colorOnSurfaceVariant, context.getTheme()); + GlideHelper.loadResource(Glide.with(context), R.drawable.ic_outline_add_24, tint, _imageView); } else { GlideHelper.loadIconFile(Glide.with(context), _iconFile, _iconType, _imageView); } diff --git a/app/src/main/res/color/bg_chip_color.xml b/app/src/main/res/color/bg_chip_color.xml deleted file mode 100644 index 49f20732..00000000 --- a/app/src/main/res/color/bg_chip_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/bg_chip_text_color.xml b/app/src/main/res/color/bg_chip_text_color.xml deleted file mode 100644 index 3ff71a3e..00000000 --- a/app/src/main/res/color/bg_chip_text_color.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/dialog_button_color.xml b/app/src/main/res/color/dialog_button_color.xml index 90c773d5..6abb6590 100644 --- a/app/src/main/res/color/dialog_button_color.xml +++ b/app/src/main/res/color/dialog_button_color.xml @@ -1,5 +1,5 @@ - - + + diff --git a/app/src/main/res/color/disabled_textview_colors.xml b/app/src/main/res/color/disabled_textview_colors.xml deleted file mode 100644 index adbd5b7e..00000000 --- a/app/src/main/res/color/disabled_textview_colors.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/text_input_box_icon_dark.xml b/app/src/main/res/color/text_input_box_icon_dark.xml deleted file mode 100644 index be0cce59..00000000 --- a/app/src/main/res/color/text_input_box_icon_dark.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/text_input_box_stroke_dark.xml b/app/src/main/res/color/text_input_box_stroke_dark.xml deleted file mode 100644 index 378a7381..00000000 --- a/app/src/main/res/color/text_input_box_stroke_dark.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable-anydpi/ic_action_sort.xml b/app/src/main/res/drawable-anydpi/ic_action_sort.xml deleted file mode 100644 index ef66d1c4..00000000 --- a/app/src/main/res/drawable-anydpi/ic_action_sort.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable-anydpi/ic_set_favorite.xml b/app/src/main/res/drawable-anydpi/ic_set_favorite.xml deleted file mode 100644 index 13942be1..00000000 --- a/app/src/main/res/drawable-anydpi/ic_set_favorite.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable-anydpi/ic_unset_favorite.xml b/app/src/main/res/drawable-anydpi/ic_unset_favorite.xml deleted file mode 100644 index 7752b92f..00000000 --- a/app/src/main/res/drawable-anydpi/ic_unset_favorite.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable-hdpi/ic_action_sort.png b/app/src/main/res/drawable-hdpi/ic_action_sort.png deleted file mode 100644 index fe9573f4..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_sort.png b/app/src/main/res/drawable-mdpi/ic_action_sort.png deleted file mode 100644 index a9588ed3..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-v24/ic_launcher_background.xml b/app/src/main/res/drawable-v24/ic_launcher_background.xml deleted file mode 100644 index fd4e36ba..00000000 --- a/app/src/main/res/drawable-v24/ic_launcher_background.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v24/rounded_dialog.xml b/app/src/main/res/drawable-v24/rounded_dialog.xml deleted file mode 100644 index bd708710..00000000 --- a/app/src/main/res/drawable-v24/rounded_dialog.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable-xhdpi/ic_action_sort.png b/app/src/main/res/drawable-xhdpi/ic_action_sort.png deleted file mode 100644 index 2184723d..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_sort.png b/app/src/main/res/drawable-xxhdpi/ic_action_sort.png deleted file mode 100644 index ca1da315..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_sort.png and /dev/null differ diff --git a/app/src/main/res/drawable/baseline_arrow_right_24.xml b/app/src/main/res/drawable/baseline_arrow_right_24.xml index e3b8f37b..0c739cb2 100644 --- a/app/src/main/res/drawable/baseline_arrow_right_24.xml +++ b/app/src/main/res/drawable/baseline_arrow_right_24.xml @@ -1,5 +1,11 @@ - - + + diff --git a/app/src/main/res/drawable/circular_button_background.xml b/app/src/main/res/drawable/circular_button_background.xml deleted file mode 100644 index dd746464..00000000 --- a/app/src/main/res/drawable/circular_button_background.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/circular_button_done.xml b/app/src/main/res/drawable/circular_button_done.xml deleted file mode 100644 index 9b2563eb..00000000 --- a/app/src/main/res/drawable/circular_button_done.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/circular_button_next.xml b/app/src/main/res/drawable/circular_button_next.xml deleted file mode 100644 index 36065dc7..00000000 --- a/app/src/main/res/drawable/circular_button_next.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/circular_button_prev.xml b/app/src/main/res/drawable/circular_button_prev.xml deleted file mode 100644 index 4fc70293..00000000 --- a/app/src/main/res/drawable/circular_button_prev.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/drag_handle.xml b/app/src/main/res/drawable/drag_handle.xml deleted file mode 100644 index 2a8df473..00000000 --- a/app/src/main/res/drawable/drag_handle.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/drawable/fab_label_background.xml b/app/src/main/res/drawable/fab_label_background.xml deleted file mode 100644 index 908cf84a..00000000 --- a/app/src/main/res/drawable/fab_label_background.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/button_rounded_corners.xml b/app/src/main/res/drawable/favorite_indicator.xml similarity index 52% rename from app/src/main/res/drawable/button_rounded_corners.xml rename to app/src/main/res/drawable/favorite_indicator.xml index 20b385ab..ae283bcd 100644 --- a/app/src/main/res/drawable/button_rounded_corners.xml +++ b/app/src/main/res/drawable/favorite_indicator.xml @@ -2,9 +2,8 @@ - - - + + diff --git a/app/src/main/res/drawable/ic_add_black_24dp.xml b/app/src/main/res/drawable/ic_add_black_24dp.xml deleted file mode 100644 index 0258249c..00000000 --- a/app/src/main/res/drawable/ic_add_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_add_photo_24px.xml b/app/src/main/res/drawable/ic_add_photo_24px.xml deleted file mode 100644 index f7f4a1ea..00000000 --- a/app/src/main/res/drawable/ic_add_photo_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_alert_black_24dp.xml b/app/src/main/res/drawable/ic_alert_black_24dp.xml deleted file mode 100644 index 6ed4cfd7..00000000 --- a/app/src/main/res/drawable/ic_alert_black_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_android.xml b/app/src/main/res/drawable/ic_android.xml deleted file mode 100644 index af157bd9..00000000 --- a/app/src/main/res/drawable/ic_android.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_left_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_left_black_24dp.xml deleted file mode 100644 index aff49cb5..00000000 --- a/app/src/main/res/drawable/ic_arrow_left_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_right_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_right_black_24dp.xml deleted file mode 100644 index 461a6018..00000000 --- a/app/src/main/res/drawable/ic_arrow_right_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_fiber_pin_24.xml b/app/src/main/res/drawable/ic_baseline_fiber_pin_24.xml deleted file mode 100644 index 957a249f..00000000 --- a/app/src/main/res/drawable/ic_baseline_fiber_pin_24.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_baseline_filter_list_24dp.xml b/app/src/main/res/drawable/ic_baseline_filter_list_24dp.xml deleted file mode 100644 index 997895c9..00000000 --- a/app/src/main/res/drawable/ic_baseline_filter_list_24dp.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_baseline_menu_black_32.xml b/app/src/main/res/drawable/ic_baseline_menu_black_32.xml deleted file mode 100644 index cde3883c..00000000 --- a/app/src/main/res/drawable/ic_baseline_menu_black_32.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_baseline_notes_black_24.xml b/app/src/main/res/drawable/ic_baseline_notes_black_24.xml deleted file mode 100644 index c1925c7d..00000000 --- a/app/src/main/res/drawable/ic_baseline_notes_black_24.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_brush_black_24dp.xml b/app/src/main/res/drawable/ic_brush_black_24dp.xml deleted file mode 100644 index 913e34cf..00000000 --- a/app/src/main/res/drawable/ic_brush_black_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_camera_front_24dp.xml b/app/src/main/res/drawable/ic_camera_front_24dp.xml deleted file mode 100644 index 0f70d89b..00000000 --- a/app/src/main/res/drawable/ic_camera_front_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_camera_rear_24dp.xml b/app/src/main/res/drawable/ic_camera_rear_24dp.xml deleted file mode 100644 index 1c9724b0..00000000 --- a/app/src/main/res/drawable/ic_camera_rear_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_check_black_24dp.xml b/app/src/main/res/drawable/ic_check_black_24dp.xml deleted file mode 100644 index d986bb97..00000000 --- a/app/src/main/res/drawable/ic_check_black_24dp.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chevron_down_black_24dp.xml b/app/src/main/res/drawable/ic_chevron_down_black_24dp.xml deleted file mode 100644 index 73334a0e..00000000 --- a/app/src/main/res/drawable/ic_chevron_down_black_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml deleted file mode 100644 index b5c7319f..00000000 --- a/app/src/main/res/drawable/ic_close.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/ic_cloud_upload_outline_black_24dp.xml b/app/src/main/res/drawable/ic_cloud_upload_outline_black_24dp.xml deleted file mode 100644 index 50f2f687..00000000 --- a/app/src/main/res/drawable/ic_cloud_upload_outline_black_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_content_copy_white_24dp.xml b/app/src/main/res/drawable/ic_content_copy_white_24dp.xml deleted file mode 100644 index 1e689ac6..00000000 --- a/app/src/main/res/drawable/ic_content_copy_white_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_counter_black_24dp.xml b/app/src/main/res/drawable/ic_counter_black_24.xml similarity index 90% rename from app/src/main/res/drawable/ic_counter_black_24dp.xml rename to app/src/main/res/drawable/ic_counter_black_24.xml index 30ac856e..885620b9 100644 --- a/app/src/main/res/drawable/ic_counter_black_24dp.xml +++ b/app/src/main/res/drawable/ic_counter_black_24.xml @@ -2,6 +2,7 @@ android:height="24dp" android:width="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_create_black_24dp.xml b/app/src/main/res/drawable/ic_create_black_24dp.xml deleted file mode 100644 index 2ab2fb75..00000000 --- a/app/src/main/res/drawable/ic_create_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete_black_24dp.xml deleted file mode 100644 index 39e64d69..00000000 --- a/app/src/main/res/drawable/ic_delete_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml deleted file mode 100644 index 8bed121a..00000000 --- a/app/src/main/res/drawable/ic_delete_white.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_done_all_black_24dp.xml b/app/src/main/res/drawable/ic_done_all_black_24dp.xml deleted file mode 100644 index dfe4814d..00000000 --- a/app/src/main/res/drawable/ic_done_all_black_24dp.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_done_black_24dp.xml b/app/src/main/res/drawable/ic_done_black_24dp.xml deleted file mode 100644 index 7affe9ba..00000000 --- a/app/src/main/res/drawable/ic_done_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_dots_vertical_black_24dp.xml b/app/src/main/res/drawable/ic_dots_vertical_black_24dp.xml deleted file mode 100644 index 9a6a9845..00000000 --- a/app/src/main/res/drawable/ic_dots_vertical_black_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_filled_star_24.xml b/app/src/main/res/drawable/ic_filled_star_24.xml new file mode 100644 index 00000000..1172be74 --- /dev/null +++ b/app/src/main/res/drawable/ic_filled_star_24.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_fingerprint_black_24dp.xml b/app/src/main/res/drawable/ic_fingerprint_black_24dp.xml deleted file mode 100644 index d0f76e34..00000000 --- a/app/src/main/res/drawable/ic_fingerprint_black_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_gesture_tap_24dp.xml b/app/src/main/res/drawable/ic_gesture_tap_24dp.xml deleted file mode 100644 index 0bd74d8b..00000000 --- a/app/src/main/res/drawable/ic_gesture_tap_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_icon_unselected.xml b/app/src/main/res/drawable/ic_icon_unselected.xml deleted file mode 100644 index d60f1680..00000000 --- a/app/src/main/res/drawable/ic_icon_unselected.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_info_outline_black_24dp.xml b/app/src/main/res/drawable/ic_info_outline_black_24dp.xml deleted file mode 100644 index ab95f29e..00000000 --- a/app/src/main/res/drawable/ic_info_outline_black_24dp.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml deleted file mode 100644 index ad33063c..00000000 --- a/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index c7bd21db..00000000 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_layers_black_24dp.xml b/app/src/main/res/drawable/ic_layers_black_24dp.xml deleted file mode 100644 index 84f5bb50..00000000 --- a/app/src/main/res/drawable/ic_layers_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_lock.xml b/app/src/main/res/drawable/ic_lock.xml deleted file mode 100644 index 1987c062..00000000 --- a/app/src/main/res/drawable/ic_lock.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_mode_edit.xml b/app/src/main/res/drawable/ic_mode_edit.xml deleted file mode 100644 index 46462b57..00000000 --- a/app/src/main/res/drawable/ic_mode_edit.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_outline_add_24.xml b/app/src/main/res/drawable/ic_outline_add_24.xml new file mode 100644 index 00000000..40c23537 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_add_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_add_photo_alternate_24.xml b/app/src/main/res/drawable/ic_outline_add_photo_alternate_24.xml new file mode 100644 index 00000000..93980c52 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_add_photo_alternate_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_android_24.xml b/app/src/main/res/drawable/ic_outline_android_24.xml new file mode 100644 index 00000000..f2c7005d --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_android_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_arrow_left_alt_24.xml b/app/src/main/res/drawable/ic_outline_arrow_left_alt_24.xml new file mode 100644 index 00000000..88603a45 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_arrow_left_alt_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_arrow_right_alt_24.xml b/app/src/main/res/drawable/ic_outline_arrow_right_alt_24.xml new file mode 100644 index 00000000..aff8e219 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_arrow_right_alt_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_brush_24.xml b/app/src/main/res/drawable/ic_outline_brush_24.xml new file mode 100644 index 00000000..4ba51513 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_brush_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_camera_front_24.xml b/app/src/main/res/drawable/ic_outline_camera_front_24.xml new file mode 100644 index 00000000..2dc5475b --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_camera_front_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_camera_rear_24.xml b/app/src/main/res/drawable/ic_outline_camera_rear_24.xml new file mode 100644 index 00000000..c4e7cb02 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_camera_rear_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_check_24.xml b/app/src/main/res/drawable/ic_outline_check_24.xml new file mode 100644 index 00000000..034ea238 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_check_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_close_24.xml b/app/src/main/res/drawable/ic_outline_close_24.xml new file mode 100644 index 00000000..fe302f56 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_close_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_cloud_upload_24.xml b/app/src/main/res/drawable/ic_outline_cloud_upload_24.xml new file mode 100644 index 00000000..87071b00 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_cloud_upload_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_code_24.xml b/app/src/main/res/drawable/ic_outline_code_24.xml new file mode 100644 index 00000000..b1c70298 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_code_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_construction_24.xml b/app/src/main/res/drawable/ic_outline_construction_24.xml new file mode 100644 index 00000000..2d6a3d3b --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_construction_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_content_copy_24.xml b/app/src/main/res/drawable/ic_outline_content_copy_24.xml new file mode 100644 index 00000000..be8d9ba9 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_content_copy_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_delete_24.xml b/app/src/main/res/drawable/ic_outline_delete_24.xml new file mode 100644 index 00000000..d7de5795 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_delete_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_description_24.xml b/app/src/main/res/drawable/ic_outline_description_24.xml new file mode 100644 index 00000000..54604506 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_description_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_done_all_24.xml b/app/src/main/res/drawable/ic_outline_done_all_24.xml new file mode 100644 index 00000000..646f4c5f --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_done_all_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_edit_24.xml b/app/src/main/res/drawable/ic_outline_edit_24.xml new file mode 100644 index 00000000..ce76cb6d --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_edit_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_error_24.xml b/app/src/main/res/drawable/ic_outline_error_24.xml new file mode 100644 index 00000000..4d0faf6e --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_error_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_expand_more_24.xml b/app/src/main/res/drawable/ic_outline_expand_more_24.xml new file mode 100644 index 00000000..fff246ca --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_expand_more_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_fiber_pin_24.xml b/app/src/main/res/drawable/ic_outline_fiber_pin_24.xml new file mode 100644 index 00000000..25eb5f1d --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_fiber_pin_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_filter_list_24.xml b/app/src/main/res/drawable/ic_outline_filter_list_24.xml new file mode 100644 index 00000000..ac6b9761 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_filter_list_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_history_24.xml b/app/src/main/res/drawable/ic_outline_history_24.xml new file mode 100644 index 00000000..f6a2288f --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_history_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_info_24.xml b/app/src/main/res/drawable/ic_outline_info_24.xml new file mode 100644 index 00000000..4b939194 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_info_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_key_24.xml b/app/src/main/res/drawable/ic_outline_key_24.xml new file mode 100644 index 00000000..c2890642 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_key_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_layers_24.xml b/app/src/main/res/drawable/ic_outline_layers_24.xml new file mode 100644 index 00000000..89074479 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_layers_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_lock_24.xml b/app/src/main/res/drawable/ic_outline_lock_24.xml new file mode 100644 index 00000000..cbf45968 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_lock_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_mail_24.xml b/app/src/main/res/drawable/ic_outline_mail_24.xml new file mode 100644 index 00000000..62da4745 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_mail_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_menu_24.xml b/app/src/main/res/drawable/ic_outline_menu_24.xml new file mode 100644 index 00000000..b33cfc1f --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_menu_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_more_vert_24.xml b/app/src/main/res/drawable/ic_outline_more_vert_24.xml new file mode 100644 index 00000000..1ff4b01a --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_more_vert_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_notes_24.xml b/app/src/main/res/drawable/ic_outline_notes_24.xml new file mode 100644 index 00000000..0b9beb2d --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_notes_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_package_variant_24.xml b/app/src/main/res/drawable/ic_outline_package_variant_24.xml new file mode 100644 index 00000000..a87b00d0 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_package_variant_24.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_outline_person_24.xml b/app/src/main/res/drawable/ic_outline_person_24.xml new file mode 100644 index 00000000..c1a494a4 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_person_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_public_24.xml b/app/src/main/res/drawable/ic_outline_public_24.xml new file mode 100644 index 00000000..5f047654 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_public_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_qr_code_2_24.xml b/app/src/main/res/drawable/ic_outline_qr_code_2_24.xml new file mode 100644 index 00000000..ba2653ea --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_qr_code_2_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_refresh_24.xml b/app/src/main/res/drawable/ic_outline_refresh_24.xml new file mode 100644 index 00000000..c70bd4e6 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_refresh_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_reset_image_24.xml b/app/src/main/res/drawable/ic_outline_reset_image_24.xml new file mode 100644 index 00000000..76050c2e --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_reset_image_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_sort_24.xml b/app/src/main/res/drawable/ic_outline_sort_24.xml new file mode 100644 index 00000000..955f3c64 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_sort_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_star_24.xml b/app/src/main/res/drawable/ic_outline_star_24.xml new file mode 100644 index 00000000..7757a988 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_star_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_touch_app_24.xml b/app/src/main/res/drawable/ic_outline_touch_app_24.xml new file mode 100644 index 00000000..d9046698 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_touch_app_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_outline_warning_24.xml b/app/src/main/res/drawable/ic_outline_warning_24.xml new file mode 100644 index 00000000..f53029a6 --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_warning_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_package_variant_black_24dp.xml b/app/src/main/res/drawable/ic_package_variant_black_24dp.xml deleted file mode 100644 index ee927181..00000000 --- a/app/src/main/res/drawable/ic_package_variant_black_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_person_black_24dp.xml b/app/src/main/res/drawable/ic_person_black_24dp.xml deleted file mode 100644 index b2cb337b..00000000 --- a/app/src/main/res/drawable/ic_person_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_plus_black_24dp.xml b/app/src/main/res/drawable/ic_plus_black_24dp.xml deleted file mode 100644 index ddd6dfe6..00000000 --- a/app/src/main/res/drawable/ic_plus_black_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_qr_code_full.xml b/app/src/main/res/drawable/ic_qr_code_full.xml deleted file mode 100644 index 9b5e128f..00000000 --- a/app/src/main/res/drawable/ic_qr_code_full.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_qrcode_scan.xml b/app/src/main/res/drawable/ic_qrcode_scan.xml index ee1670e0..69281097 100644 --- a/app/src/main/res/drawable/ic_qrcode_scan.xml +++ b/app/src/main/res/drawable/ic_qrcode_scan.xml @@ -1,8 +1,11 @@ - + diff --git a/app/src/main/res/drawable/ic_refresh_black_24dp.xml b/app/src/main/res/drawable/ic_refresh_black_24dp.xml deleted file mode 100644 index 5e434f43..00000000 --- a/app/src/main/res/drawable/ic_refresh_black_24dp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_reset_image.xml b/app/src/main/res/drawable/ic_reset_image.xml deleted file mode 100644 index c42849c4..00000000 --- a/app/src/main/res/drawable/ic_reset_image.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_tools_black_24dp.xml b/app/src/main/res/drawable/ic_tools_black_24dp.xml deleted file mode 100644 index 42af86dd..00000000 --- a/app/src/main/res/drawable/ic_tools_black_24dp.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_unselected.xml b/app/src/main/res/drawable/ic_unselected.xml new file mode 100644 index 00000000..5ea9582f --- /dev/null +++ b/app/src/main/res/drawable/ic_unselected.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_vpn_key_black_24dp.xml b/app/src/main/res/drawable/ic_vpn_key_black_24dp.xml deleted file mode 100644 index 2eddd16f..00000000 --- a/app/src/main/res/drawable/ic_vpn_key_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/item_selected.xml b/app/src/main/res/drawable/item_selected.xml index 040cdcbe..8e17b320 100644 --- a/app/src/main/res/drawable/item_selected.xml +++ b/app/src/main/res/drawable/item_selected.xml @@ -9,4 +9,4 @@ > - + \ No newline at end of file diff --git a/app/src/main/res/drawable/progress_horizontal.xml b/app/src/main/res/drawable/progress_horizontal.xml index d4abd09d..bb5fdac4 100644 --- a/app/src/main/res/drawable/progress_horizontal.xml +++ b/app/src/main/res/drawable/progress_horizontal.xml @@ -2,9 +2,8 @@ - + - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_background.xml b/app/src/main/res/drawable/rounded_background.xml index e2a884d8..682c748a 100644 --- a/app/src/main/res/drawable/rounded_background.xml +++ b/app/src/main/res/drawable/rounded_background.xml @@ -1,6 +1,6 @@ - + diff --git a/app/src/main/res/drawable/rounded_popup.xml b/app/src/main/res/drawable/rounded_popup.xml new file mode 100644 index 00000000..1a3e3c4e --- /dev/null +++ b/app/src/main/res/drawable/rounded_popup.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 2caa4ad2..8a6c3b51 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -4,17 +4,16 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/background" + android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.AboutActivity"> - + + android:layout_height="?attr/actionBarSize" /> + android:fitsSystemWindows="true"> + android:layout_height="?attr/actionBarSize" /> + android:textSize="32sp"/> + app:passwordToggleTint="?attr/colorOnSurface"> + android:text="@string/unlock" /> @@ -109,10 +100,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center" - android:textStyle="bold" - android:textAllCaps="true" android:text="@string/app_name_full" - android:paddingVertical="50dp" - android:textColor="@color/divider" /> + android:textSize="15sp" + android:textAllCaps="true" + android:textStyle="bold" + android:textColor="?attr/colorOnSurfaceDim" + android:paddingVertical="50dp" /> diff --git a/app/src/main/res/layout/activity_edit_entry.xml b/app/src/main/res/layout/activity_edit_entry.xml index 0991bf06..b45503ef 100644 --- a/app/src/main/res/layout/activity_edit_entry.xml +++ b/app/src/main/res/layout/activity_edit_entry.xml @@ -1,27 +1,27 @@ - - + + android:layout_height="?attr/actionBarSize" /> + android:layout_height="wrap_content" + android:clipToPadding="false" + android:isScrollContainer="true" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + android:src="@drawable/ic_outline_check_24" + app:tint="?attr/colorOnSurface" /> - + android:layout_height="wrap_content" /> @@ -138,8 +136,8 @@ @@ -164,8 +162,8 @@ @@ -174,7 +172,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - app:passwordToggleTint="#949494" + app:passwordToggleTint="?attr/colorOnSurface" app:passwordToggleEnabled="true"> @@ -206,7 +204,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - app:passwordToggleTint="#949494" + app:passwordToggleTint="?attr/colorOnSurface" app:passwordToggleEnabled="true"> + android:src="@drawable/ic_outline_expand_more_24" + app:tint="?attr/colorOnSurface" /> @@ -352,8 +350,8 @@ @@ -382,4 +380,4 @@ - + diff --git a/app/src/main/res/layout/activity_groups.xml b/app/src/main/res/layout/activity_groups.xml index d7cca180..611f4ad7 100644 --- a/app/src/main/res/layout/activity_groups.xml +++ b/app/src/main/res/layout/activity_groups.xml @@ -4,18 +4,17 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/background" + android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.GroupManagerActivity"> - + + android:layout_height="?attr/actionBarSize" /> + android:src="@drawable/ic_outline_layers_24" /> - + + android:layout_height="?attr/actionBarSize" /> + android:src="@drawable/ic_outline_check_24" /> diff --git a/app/src/main/res/layout/activity_intro.xml b/app/src/main/res/layout/activity_intro.xml index 79600e46..e2e4b8cc 100644 --- a/app/src/main/res/layout/activity_intro.xml +++ b/app/src/main/res/layout/activity_intro.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/background" + android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.IntroActivity"> - + app:layout_constraintStart_toStartOf="parent" + style="@style/Widget.Material3.Button.IconButton.Filled.Tonal" /> - + app:layout_constraintEnd_toEndOf="parent" + style="@style/Widget.Material3.Button.IconButton.Filled.Tonal" /> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index f2b26f43..ccc10366 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,17 +5,20 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:fitsSystemWindows="true" tools:context="com.beemdevelopment.aegis.ui.MainActivity"> - + + android:layout_height="?attr/actionBarSize" /> - - - - + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + android:src="@drawable/ic_outline_add_24" /> diff --git a/app/src/main/res/layout/activity_preferences.xml b/app/src/main/res/layout/activity_preferences.xml index b16858f8..7bc815f2 100644 --- a/app/src/main/res/layout/activity_preferences.xml +++ b/app/src/main/res/layout/activity_preferences.xml @@ -1,22 +1,23 @@ - + xmlns:app="http://schemas.android.com/apk/res-auto" + android:orientation="vertical" + android:fitsSystemWindows="true"> - + + android:layout_height="?attr/actionBarSize" /> - + android:layout_height="match_parent" + android:isScrollContainer="true" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + diff --git a/app/src/main/res/layout/activity_scanner.xml b/app/src/main/res/layout/activity_scanner.xml index 2516c89a..64814633 100644 --- a/app/src/main/res/layout/activity_scanner.xml +++ b/app/src/main/res/layout/activity_scanner.xml @@ -1,10 +1,11 @@ - - + + android:layout_height="?attr/actionBarSize" + app:titleTextColor="?attr/colorOnDark" /> + android:layout_height="match_parent" /> - + diff --git a/app/src/main/res/layout/activity_share_entry.xml b/app/src/main/res/layout/activity_share_entry.xml index 9044a0ec..b7e49718 100644 --- a/app/src/main/res/layout/activity_share_entry.xml +++ b/app/src/main/res/layout/activity_share_entry.xml @@ -1,132 +1,131 @@ - - + + + android:layout_height="?attr/actionBarSize" /> + - + - + - + - + - + -