diff options
53 files changed, 451 insertions, 344 deletions
diff --git a/app/build.gradle b/app/build.gradle index 0297229b..48677bf6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -101,7 +101,7 @@ dependencies { implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.work:work-runtime:2.7.1' - implementation 'com.google.android.material:material:1.6.1' + implementation 'com.google.android.material:material:1.7.0' // Database implementation 'androidx.room:room-runtime:2.4.3' diff --git a/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java index 56350be7..8caa4540 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java @@ -10,9 +10,9 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; -import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import java.util.ArrayList; import java.util.Collection; @@ -21,13 +21,11 @@ import java.util.Objects; import java.util.stream.Collectors; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.branding.BrandedAlertDialogBuilder; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; import it.niedermann.owncloud.notes.databinding.DialogChooseAccountBinding; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.account.AccountChooserAdapter; -import it.niedermann.owncloud.notes.shared.account.AccountChooserViewHolder; /** * A {@link DialogFragment} which provides an {@link Account} chooser that hides the current {@link Account}. @@ -75,7 +73,7 @@ public class AccountPickerDialogFragment extends BrandedDialogFragment { @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - final var dialogBuilder = new BrandedAlertDialogBuilder(requireActivity()) + final var dialogBuilder = new MaterialAlertDialogBuilder(requireActivity()) .setTitle(R.string.simple_move) .setNegativeButton(android.R.string.cancel, null); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java index b15f6308..7d088afe 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java @@ -1,5 +1,7 @@ package it.niedermann.owncloud.notes.accountswitcher; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToLayerDrawable; + import android.app.Dialog; import android.content.Context; import android.content.Intent; @@ -8,14 +10,11 @@ import android.net.Uri; import android.os.Bundle; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; -import androidx.lifecycle.LiveData; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; - -import java.util.List; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; @@ -24,8 +23,6 @@ import it.niedermann.owncloud.notes.manageaccounts.ManageAccountsActivity; import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Account; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToLayerDrawable; - /** * Displays all available {@link Account} entries and provides basic operations for them, like adding or switching */ @@ -104,7 +101,7 @@ public class AccountSwitcherDialog extends BrandedDialogFragment { dismiss(); }); - return new AlertDialog.Builder(requireContext()) + return new MaterialAlertDialogBuilder(requireContext()) .setView(binding.getRoot()) .create(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedAlertDialogBuilder.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedAlertDialogBuilder.java deleted file mode 100644 index c48e6298..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedAlertDialogBuilder.java +++ /dev/null @@ -1,48 +0,0 @@ -package it.niedermann.owncloud.notes.branding; - -import android.content.Context; -import android.content.DialogInterface; -import android.widget.Button; - -import androidx.annotation.CallSuper; -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; - -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme; - -public class BrandedAlertDialogBuilder extends AlertDialog.Builder implements Branded { - - protected AlertDialog dialog; - - public BrandedAlertDialogBuilder(Context context) { - super(context); - } - - @NonNull - @Override - public AlertDialog create() { - this.dialog = super.create(); - - @NonNull final var context = getContext(); - @ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context); - @ColorInt final int textColor = BrandingUtil.readBrandTextColor(context); - applyBrand(mainColor, textColor); - dialog.setOnShowListener(dialog -> applyBrand(mainColor, textColor)); - return dialog; - } - - @CallSuper - @Override - public void applyBrand(int mainColor, int textColor) { - final var buttons = new Button[3]; - buttons[0] = dialog.getButton(DialogInterface.BUTTON_POSITIVE); - buttons[1] = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); - buttons[2] = dialog.getButton(DialogInterface.BUTTON_NEUTRAL); - for (final var button : buttons) { - if (button != null) { - button.setTextColor(getSecondaryForegroundColorDependingOnTheme(button.getContext(), mainColor)); - } - } - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDeleteAlertDialogBuilder.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDeleteAlertDialogBuilder.java deleted file mode 100644 index e50b6fcb..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDeleteAlertDialogBuilder.java +++ /dev/null @@ -1,26 +0,0 @@ -package it.niedermann.owncloud.notes.branding; - -import android.content.Context; -import android.content.DialogInterface; -import android.widget.Button; - -import androidx.annotation.CallSuper; - -import it.niedermann.owncloud.notes.R; - -public class BrandedDeleteAlertDialogBuilder extends BrandedAlertDialogBuilder { - - public BrandedDeleteAlertDialogBuilder(Context context) { - super(context); - } - - @CallSuper - @Override - public void applyBrand(int mainColor, int textColor) { - super.applyBrand(mainColor, textColor); - final var positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE); - if (positiveButton != null) { - positiveButton.setTextColor(getContext().getResources().getColor(R.color.bg_attention)); - } - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java index 8e3a4d9f..1c0ebf11 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java @@ -1,28 +1,46 @@ package it.niedermann.owncloud.notes.branding; +import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.getAttribute; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColor; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; + import android.graphics.Color; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import com.google.android.material.snackbar.BaseTransientBottomBar; import com.google.android.material.snackbar.Snackbar; -import it.niedermann.android.util.ColorUtil; +import it.niedermann.owncloud.notes.R; public class BrandedSnackbar { @NonNull - public static Snackbar make(@NonNull View view, @NonNull CharSequence text, @Snackbar.Duration int duration) { + public static Snackbar make(@NonNull View view, @NonNull CharSequence text, @BaseTransientBottomBar.Duration int duration) { final var snackbar = Snackbar.make(view, text, duration); - final int color = BrandingUtil.readBrandMainColor(view.getContext()); - snackbar.setActionTextColor(ColorUtil.INSTANCE.isColorDark(color) ? Color.WHITE : color); + + @ColorInt final int backgroundColor = getAttribute(view.getContext(), R.attr.colorSurfaceInverse); + @ColorInt final int color = readBrandMainColor(view.getContext()); + + if (contrastRatioIsSufficient(backgroundColor, color)) { + snackbar.setActionTextColor(color); + } else { + if (isDarkThemeActive(view.getContext())) { + snackbar.setActionTextColor(Color.BLACK); + } else { + snackbar.setActionTextColor(Color.WHITE); + } + } + return snackbar; } @NonNull - public static Snackbar make(@NonNull View view, @StringRes int resId, @Snackbar.Duration int duration) { + public static Snackbar make(@NonNull View view, @StringRes int resId, @BaseTransientBottomBar.Duration int duration) { return make(view, view.getResources().getText(resId), duration); } - }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java index af2b4a43..ba79fa0e 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java @@ -1,15 +1,19 @@ package it.niedermann.owncloud.notes.branding; +import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficientBigAreas; + import android.content.Context; -import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.util.Log; +import android.util.TypedValue; import android.view.MenuItem; import android.widget.EditText; +import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.IdRes; import androidx.annotation.NonNull; @@ -21,11 +25,13 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; import androidx.preference.PreferenceManager; +import com.google.android.material.textfield.TextInputLayout; + import it.niedermann.android.sharedpreferences.SharedPreferenceIntLiveData; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; - -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; +import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; public class BrandingUtil { @@ -144,6 +150,17 @@ public class BrandingUtil { )); } + public static void applyBrandToEditTextInputLayout(@ColorInt int color, @NonNull TextInputLayout til) { + final int colorPrimary = ContextCompat.getColor(til.getContext(), R.color.primary); + final int colorAccent = ContextCompat.getColor(til.getContext(), R.color.accent); + final var colorDanger = ColorStateList.valueOf(ContextCompat.getColor(til.getContext(), R.color.danger)); + til.setBoxStrokeColor(contrastRatioIsSufficientBigAreas(color, colorPrimary) ? color : colorAccent); + til.setHintTextColor(ColorStateList.valueOf(contrastRatioIsSufficient(color, colorPrimary) ? color : colorAccent)); + til.setErrorTextColor(colorDanger); + til.setBoxStrokeErrorColor(colorDanger); + til.setErrorIconTintList(colorDanger); + } + public static void tintMenuIcon(@NonNull MenuItem menuItem, @ColorInt int color) { var drawable = menuItem.getIcon(); if (drawable != null) { @@ -161,4 +178,44 @@ public class BrandingUtil { DrawableCompat.setTint(drawable, mainColor); } } + + @ColorInt + public static int getAttribute(@NonNull Context context, @AttrRes int id) { + final var typedValue = new TypedValue(); + context.getTheme().resolveAttribute(id, typedValue, true); + return typedValue.data; + } + + @ColorInt + public static int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { + if (isDarkThemeActive(context)) { // Dark background + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + return mainColor; + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } else { // Light brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } + } else { // Light background + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } else { // Light brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + return mainColor; + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } + } + } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/DeleteAlertDialogBuilder.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/DeleteAlertDialogBuilder.java new file mode 100644 index 00000000..e51b5024 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/DeleteAlertDialogBuilder.java @@ -0,0 +1,37 @@ +package it.niedermann.owncloud.notes.branding; + +import android.content.Context; +import android.content.DialogInterface; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.ContextCompat; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import it.niedermann.owncloud.notes.R; + +public class DeleteAlertDialogBuilder extends MaterialAlertDialogBuilder { + + protected AlertDialog dialog; + + public DeleteAlertDialogBuilder(Context context) { + super(context); + } + + @NonNull + @Override + public AlertDialog create() { + this.dialog = super.create(); + applyBrand(); + dialog.setOnShowListener(dialog -> applyBrand()); + return dialog; + } + + public void applyBrand() { + final var positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE); + if (positiveButton != null) { + positiveButton.setTextColor(ContextCompat.getColor(getContext(), R.color.danger)); + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java index 6a13d8b7..b524e2fb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java @@ -370,39 +370,6 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego listener.close(); } - @ColorInt - protected static int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { - if (isDarkThemeActive(context)) { // Dark background - if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text - return mainColor; - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } else { // Light brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text - return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } - } else { // Light background - if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text - return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } else { // Light brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text - return mainColor; - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } - } - } - public interface NoteFragmentListener { void close(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java index 6733f4d3..081c60d8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java @@ -1,7 +1,10 @@ package it.niedermann.owncloud.notes.edit; +import static androidx.core.view.ViewCompat.isAttachedToWindow; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.getTextHighlightBackgroundColor; +import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; + import android.content.Context; -import android.content.SharedPreferences; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; @@ -31,9 +34,6 @@ import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; import it.niedermann.owncloud.notes.shared.util.DisplayUtils; -import static androidx.core.view.ViewCompat.isAttachedToWindow; -import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; - public class NoteEditFragment extends SearchableBaseNoteFragment { private static final String TAG = NoteEditFragment.class.getSimpleName(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java index 9d26f500..52db93a4 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java @@ -1,7 +1,10 @@ package it.niedermann.owncloud.notes.edit; +import static androidx.core.view.ViewCompat.isAttachedToWindow; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.getTextHighlightBackgroundColor; +import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; + import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Typeface; import android.os.Bundle; import android.text.Layout; @@ -27,13 +30,9 @@ import com.nextcloud.android.sso.helper.SingleAccountHelper; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.databinding.FragmentNotePreviewBinding; -import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.util.SSOUtil; -import static androidx.core.view.ViewCompat.isAttachedToWindow; -import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; - public class NotePreviewFragment extends SearchableBaseNoteFragment implements OnRefreshListener { private static final String TAG = NotePreviewFragment.class.getSimpleName(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java index 530a5549..c440f830 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java @@ -13,14 +13,14 @@ import android.widget.EditText; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.util.List; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.branding.BrandedAlertDialogBuilder; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.DialogChangeCategoryBinding; @@ -49,7 +49,7 @@ public class CategoryDialogFragment extends BrandedDialogFragment { @Override public void applyBrand(int mainColor, int textColor) { - BrandingUtil.applyBrandToEditText(mainColor, textColor, binding.search); + BrandingUtil.applyBrandToEditTextInputLayout(mainColor, binding.inputWrapper); } /** @@ -150,7 +150,7 @@ public class CategoryDialogFragment extends BrandedDialogFragment { } }); - return new BrandedAlertDialogBuilder(getActivity()) + return new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.change_category_title) .setView(dialogView) .setCancelable(true) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java index d372cdcb..e48ff63d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java @@ -1,6 +1,7 @@ package it.niedermann.owncloud.notes.edit.title; -import android.app.AlertDialog; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToEditTextInputLayout; + import android.app.Dialog; import android.content.Context; import android.os.Bundle; @@ -13,10 +14,13 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; import it.niedermann.owncloud.notes.databinding.DialogEditTitleBinding; -public class EditTitleDialogFragment extends DialogFragment { +public class EditTitleDialogFragment extends BrandedDialogFragment { private static final String TAG = EditTitleDialogFragment.class.getSimpleName(); static final String PARAM_OLD_TITLE = "old_title"; @@ -53,7 +57,7 @@ public class EditTitleDialogFragment extends DialogFragment { binding.title.setText(oldTitle); } - return new AlertDialog.Builder(getActivity()) + return new MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.change_note_title) .setView(dialogView) .setCancelable(true) @@ -82,6 +86,11 @@ public class EditTitleDialogFragment extends DialogFragment { return fragment; } + @Override + public void applyBrand(int mainColor, int textColor) { + applyBrandToEditTextInputLayout(mainColor, binding.inputWrapper); + } + /** * Interface that must be implemented by the calling Activity. */ diff --git a/app/src/main/java/it/niedermann/owncloud/notes/exception/ExceptionDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/exception/ExceptionDialogFragment.java index cfaa543d..ca242a7f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/exception/ExceptionDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/exception/ExceptionDialogFragment.java @@ -10,6 +10,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDialogFragment; import androidx.fragment.app.DialogFragment; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.util.ArrayList; import it.niedermann.android.util.ClipboardUtil; @@ -62,7 +64,7 @@ public class ExceptionDialogFragment extends AppCompatDialogFragment { adapter.setThrowables(throwables); - return new AlertDialog.Builder(requireActivity()) + return new MaterialAlertDialogBuilder(requireActivity()) .setView(binding.getRoot()) .setTitle(R.string.error_dialog_title) .setPositiveButton(android.R.string.copy, (a, b) -> ClipboardUtil.INSTANCE.copyToClipboard(requireContext(), getString(R.string.simple_exception), "```\n" + debugInfos + "\n```")) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java index 1c901c21..046f0e7d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java @@ -29,7 +29,6 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ActionMode; import androidx.appcompat.widget.SearchView; import androidx.coordinatorlayout.widget.CoordinatorLayout; @@ -48,6 +47,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import com.nextcloud.android.sso.AccountImporter; @@ -175,7 +175,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A runOnUiThread(() -> mainViewModel.postCurrentAccount(account)); } catch (NextcloudFilesAppAccountNotFoundException e) { // Verbose log output for https://github.com/stefan-niedermann/nextcloud-notes/issues/1256 - runOnUiThread(() -> new AlertDialog.Builder(this) + runOnUiThread(() -> new MaterialAlertDialogBuilder(this) .setTitle(NextcloudFilesAppAccountNotFoundException.class.getSimpleName()) .setMessage(R.string.backup) .setPositiveButton(R.string.simple_backup, (a, b) -> executor.submit(() -> { @@ -218,6 +218,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A mainViewModel.getSyncErrors().observe(this, exceptions -> { if (mainViewModel.containsNonInfrastructureRelatedItems(exceptions)) { BrandedSnackbar.make(coordinatorLayout, R.string.error_synchronization, Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) .setAction(R.string.simple_more, v -> ExceptionDialogFragment.newInstance(exceptions) .show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())) .show(); @@ -325,11 +326,14 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A if (t instanceof IntendedOfflineException) { Log.i(TAG, "Capabilities and notes not updated because " + nextAccount.getAccountName() + " is offline by intention."); } else if (t instanceof NetworkErrorException) { - BrandedSnackbar.make(coordinatorLayout, getString(R.string.error_sync, getString(R.string.error_no_network)), Snackbar.LENGTH_LONG).show(); + BrandedSnackbar.make(coordinatorLayout, getString(R.string.error_sync, getString(R.string.error_no_network)), Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) + .show(); } else { BrandedSnackbar.make(coordinatorLayout, R.string.error_synchronization, Snackbar.LENGTH_LONG) .setAction(R.string.simple_more, v -> ExceptionDialogFragment.newInstance(t) .show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())) + .setAnchorView(binding.activityNotesListView.fabCreate) .show(); } }); @@ -477,13 +481,18 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A if (t instanceof IntendedOfflineException) { Log.i(TAG, "Capabilities and notes not updated because " + currentAccount.getAccountName() + " is offline by intention."); } else if (t instanceof NextcloudHttpRequestFailedException && ((NextcloudHttpRequestFailedException) t).getStatusCode() == HttpURLConnection.HTTP_UNAVAILABLE) { - BrandedSnackbar.make(coordinatorLayout, R.string.error_maintenance_mode, Snackbar.LENGTH_LONG).show(); + BrandedSnackbar.make(coordinatorLayout, R.string.error_maintenance_mode, Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) + .show(); } else if (t instanceof NetworkErrorException) { - BrandedSnackbar.make(coordinatorLayout, getString(R.string.error_sync, getString(R.string.error_no_network)), Snackbar.LENGTH_LONG).show(); + BrandedSnackbar.make(coordinatorLayout, getString(R.string.error_sync, getString(R.string.error_no_network)), Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) + .show(); } else { BrandedSnackbar.make(coordinatorLayout, R.string.error_synchronization, Snackbar.LENGTH_LONG) .setAction(R.string.simple_more, v -> ExceptionDialogFragment.newInstance(t) .show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())) + .setAnchorView(binding.activityNotesListView.fabCreate) .show(); } }); @@ -500,7 +509,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A public void onSelectionChanged() { super.onSelectionChanged(); if (tracker.hasSelection() && mActionMode == null) { - mActionMode = startSupportActionMode(new MultiSelectedActionModeCallback(MainActivity.this, coordinatorLayout, mainViewModel, MainActivity.this, canMoveNoteToAnotherAccounts, tracker, getSupportFragmentManager())); + mActionMode = startSupportActionMode(new MultiSelectedActionModeCallback(MainActivity.this, coordinatorLayout, binding.activityNotesListView.fabCreate, mainViewModel, MainActivity.this, canMoveNoteToAnotherAccounts, tracker, getSupportFragmentManager())); } if (mActionMode != null) { if (tracker.hasSelection()) { @@ -515,7 +524,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A } ); - itemTouchHelper = new NotesListViewItemTouchHelper(this, mainViewModel, this, tracker, adapter, swipeRefreshLayout, coordinatorLayout, gridView); + itemTouchHelper = new NotesListViewItemTouchHelper(this, mainViewModel, this, tracker, adapter, swipeRefreshLayout, coordinatorLayout, binding.activityNotesListView.fabCreate, gridView); itemTouchHelper.attachToRecyclerView(listView); } @@ -673,7 +682,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A AccountImporter.onActivityResult(requestCode, resultCode, data, this, (ssoAccount) -> { CapabilitiesWorker.update(this); executor.submit(() -> { - final var importSnackbar = BrandedSnackbar.make(coordinatorLayout, R.string.progress_import_indeterminate, Snackbar.LENGTH_INDEFINITE); + final var importSnackbar = BrandedSnackbar.make(coordinatorLayout, R.string.progress_import_indeterminate, Snackbar.LENGTH_INDEFINITE) + .setAnchorView(binding.activityNotesListView.fabCreate); Log.i(TAG, "Added account: " + "name:" + ssoAccount.name + ", " + ssoAccount.url + ", userId" + ssoAccount.userId); try { Log.i(TAG, "Refreshing capabilities for " + ssoAccount.name); @@ -715,11 +725,15 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A runOnUiThread(() -> { mainViewModel.postCurrentAccount(mainViewModel.getLocalAccountByAccountName(ssoAccount.name)); // TODO there is already a sync in progress and results in displaying a TokenMissMatchException snackbar which conflicts with this one - coordinatorLayout.post(() -> BrandedSnackbar.make(coordinatorLayout, R.string.account_already_imported, Snackbar.LENGTH_LONG).show()); + coordinatorLayout.post(() -> BrandedSnackbar.make(coordinatorLayout, R.string.account_already_imported, Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) + .show()); }); } else if (e instanceof UnknownErrorException && e.getMessage() != null && e.getMessage().contains("No address associated with hostname")) { // https://github.com/stefan-niedermann/nextcloud-notes/issues/1014 - runOnUiThread(() -> Snackbar.make(coordinatorLayout, R.string.you_have_to_be_connected_to_the_internet_in_order_to_add_an_account, Snackbar.LENGTH_LONG).show()); + runOnUiThread(() -> Snackbar.make(coordinatorLayout, R.string.you_have_to_be_connected_to_the_internet_in_order_to_add_an_account, Snackbar.LENGTH_LONG) + .setAnchorView(binding.activityNotesListView.fabCreate) + .show()); } else { e.printStackTrace(); runOnUiThread(() -> { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java index a76b2068..194dcbc8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java @@ -42,6 +42,8 @@ public class MultiSelectedActionModeCallback implements Callback { @NonNull private final View view; @NonNull + private final View anchorView; + @NonNull private final MainViewModel mainViewModel; @NonNull private final LifecycleOwner lifecycleOwner; @@ -52,9 +54,17 @@ public class MultiSelectedActionModeCallback implements Callback { private final FragmentManager fragmentManager; public MultiSelectedActionModeCallback( - @NonNull Context context, @NonNull View view, @NonNull MainViewModel mainViewModel, @NonNull LifecycleOwner lifecycleOwner, boolean canMoveNoteToAnotherAccounts, @NonNull SelectionTracker<Long> tracker, @NonNull FragmentManager fragmentManager) { + @NonNull Context context, + @NonNull View view, + @NonNull View anchorView, + @NonNull MainViewModel mainViewModel, + @NonNull LifecycleOwner lifecycleOwner, + boolean canMoveNoteToAnotherAccounts, + @NonNull SelectionTracker<Long> tracker, + @NonNull FragmentManager fragmentManager) { this.context = context; this.view = view; + this.anchorView = anchorView; this.mainViewModel = mainViewModel; this.lifecycleOwner = lifecycleOwner; this.canMoveNoteToAnotherAccounts = canMoveNoteToAnotherAccounts; @@ -110,6 +120,7 @@ public class MultiSelectedActionModeCallback implements Callback { ? context.getString(R.string.action_note_deleted, fullNotes.get(0).getTitle()) : context.getResources().getQuantityString(R.plurals.bulk_notes_deleted, fullNotes.size(), fullNotes.size()); BrandedSnackbar.make(view, deletedSnackbarTitle, Snackbar.LENGTH_LONG) + .setAnchorView(anchorView) .setAction(R.string.action_undo, (View v) -> { for (final var deletedNote : fullNotes) { final var undoLiveData = mainViewModel.addNoteAndSync(deletedNote); @@ -119,6 +130,7 @@ public class MultiSelectedActionModeCallback implements Callback { ? context.getString(R.string.action_note_restored, fullNotes.get(0).getTitle()) : context.getResources().getQuantityString(R.plurals.bulk_notes_restored, fullNotes.size(), fullNotes.size()); BrandedSnackbar.make(view, restoreSnackbarTitle, Snackbar.LENGTH_SHORT) + .setAnchorView(anchorView) .show(); }) .show(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java index d31bb2f3..bb93b7b7 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java @@ -38,6 +38,7 @@ public class NotesListViewItemTouchHelper extends ItemTouchHelper { @NonNull ItemAdapter adapter, @NonNull SwipeRefreshLayout swipeRefreshLayout, @NonNull View view, + @NonNull View anchorView, boolean gridView) { super(new SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { private boolean swipeRefreshLayoutEnabled; @@ -81,10 +82,12 @@ public class NotesListViewItemTouchHelper extends ItemTouchHelper { deleteLiveData.observe(lifecycleOwner, (next) -> deleteLiveData.removeObservers(lifecycleOwner)); Log.v(TAG, "Item deleted through swipe ----------------------------------------------"); BrandedSnackbar.make(view, context.getString(R.string.action_note_deleted, dbNote.getTitle()), UNDO_DURATION) + .setAnchorView(anchorView) .setAction(R.string.action_undo, (View v) -> { final var undoLiveData = mainViewModel.addNoteAndSync(dbNote); undoLiveData.observe(lifecycleOwner, (o) -> undoLiveData.removeObservers(lifecycleOwner)); BrandedSnackbar.make(view, context.getString(R.string.action_note_restored, dbNote.getTitle()), Snackbar.LENGTH_SHORT) + .setAnchorView(anchorView) .show(); }) .show(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java index 8d0c253f..9492e43a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java @@ -1,14 +1,13 @@ package it.niedermann.owncloud.notes.manageaccounts; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToEditTextInputLayout; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColorLiveData; import static it.niedermann.owncloud.notes.shared.util.ApiVersionUtil.getPreferredApiVersion; import android.accounts.NetworkErrorException; import android.os.Bundle; import android.util.TypedValue; -import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.FrameLayout; -import android.widget.ProgressBar; +import android.view.View; import android.widget.Toast; import androidx.annotation.AttrRes; @@ -18,16 +17,19 @@ import androidx.annotation.Px; import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProvider; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.function.Function; import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.branding.BrandedAlertDialogBuilder; -import it.niedermann.owncloud.notes.branding.BrandedDeleteAlertDialogBuilder; +import it.niedermann.owncloud.notes.branding.DeleteAlertDialogBuilder; import it.niedermann.owncloud.notes.databinding.ActivityManageAccountsBinding; +import it.niedermann.owncloud.notes.databinding.DialogEditSettingBinding; import it.niedermann.owncloud.notes.exception.ExceptionDialogFragment; import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Account; @@ -42,6 +44,7 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc private ActivityManageAccountsBinding binding; private ManageAccountsViewModel viewModel; private ManageAccountAdapter adapter; + private final Executor executor = Executors.newSingleThreadExecutor(); @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -88,7 +91,7 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc public void onSuccess(Long unsynchronizedChangesCount) { runOnUiThread(() -> { if (unsynchronizedChangesCount > 0) { - new BrandedDeleteAlertDialogBuilder(ManageAccountsActivity.this) + new DeleteAlertDialogBuilder(ManageAccountsActivity.this) .setTitle(getString(R.string.remove_account, accountToDelete.getUserName())) .setMessage(getResources().getQuantityString(R.plurals.remove_account_message, (int) unsynchronizedChangesCount.longValue(), accountToDelete.getAccountName(), unsynchronizedChangesCount)) .setNeutralButton(android.R.string.cancel, null) @@ -129,16 +132,22 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc private void changeAccountSetting(@NonNull Account localAccount, @StringRes int title, @StringRes int message, @StringRes int successMessage, @NonNull Function<NotesSettings, String> propertyExtractor, @NonNull Function<String, NotesSettings> settingsFactory) { final var repository = NotesRepository.getInstance(getApplicationContext()); - final var editText = new EditText(this); - final var wrapper = createDialogViewWrapper(); - final var dialog = new BrandedAlertDialogBuilder(this) + final var binding = DialogEditSettingBinding.inflate(getLayoutInflater()); + final var mainColor$ = readBrandMainColorLiveData(this); + mainColor$.observe(this, color -> { + mainColor$.removeObservers(this); + applyBrandToEditTextInputLayout(color, binding.inputWrapper); + binding.progress.setIndicatorColor(color); + }); + + final var dialog = new MaterialAlertDialogBuilder(this) .setTitle(title) .setMessage(message) - .setView(wrapper) + .setView(binding.getRoot()) .setNeutralButton(android.R.string.cancel, null) .setPositiveButton(R.string.action_edit_save, (v, d) -> { - final var property = editText.getText().toString(); - new Thread(() -> { + final var property = binding.property.getText().toString(); + executor.execute(() -> { try { final var putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), settingsFactory.apply(property), getPreferredApiVersion(localAccount.getApiVersion())); putSettingsCall.enqueue(new Callback<>() { @@ -160,7 +169,7 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc } catch (NextcloudFilesAppAccountNotFoundException e) { ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); } - }).start(); + }); }) .show(); try { @@ -171,9 +180,9 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc runOnUiThread(() -> { final var body = response.body(); if (response.isSuccessful() && body != null) { - wrapper.removeAllViews(); - editText.setText(propertyExtractor.apply(body)); - wrapper.addView(editText); + binding.getRoot().removeView(binding.progress); + binding.property.setText(propertyExtractor.apply(body)); + binding.inputWrapper.setVisibility(View.VISIBLE); } else { dialog.dismiss(); ExceptionDialogFragment.newInstance(new NetworkErrorException(getString(R.string.http_status_code, response.code()))).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); @@ -195,28 +204,6 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc } } - @NonNull - private ViewGroup createDialogViewWrapper() { - final var progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal); - progressBar.setIndeterminate(true); - final var wrapper = new FrameLayout(this); - final int paddingVertical = getResources().getDimensionPixelSize(R.dimen.spacer_1x); - final int paddingHorizontal = getDimensionFromAttribute(android.R.attr.dialogPreferredPadding); - wrapper.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical); - wrapper.addView(progressBar); - return wrapper; - } - - @Px - private int getDimensionFromAttribute(@SuppressWarnings("SameParameterValue") @AttrRes int attr) { - final var typedValue = new TypedValue(); - if (getTheme().resolveAttribute(attr, typedValue, true)) - return TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics()); - else { - return 0; - } - } - @Override public void applyBrand(int mainColor, int textColor) { applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java index 035aab9a..70c5316e 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java @@ -28,6 +28,17 @@ public final class NotesColorUtil { return ret; } + public static boolean contrastRatioIsSufficientBigAreas(@ColorInt int colorOne, @ColorInt int colorTwo) { + final var key = new ColorPair(colorOne, colorTwo); + var ret = CONTRAST_RATIO_SUFFICIENT_CACHE.get(key); + if (ret == null) { + ret = ColorUtil.INSTANCE.getContrastRatio(colorOne, colorTwo) > 1.47d; + CONTRAST_RATIO_SUFFICIENT_CACHE.put(key, ret); + return ret; + } + return ret; + } + private static class ColorPair extends Pair<Integer, Integer> { private ColorPair(@Nullable Integer first, @Nullable Integer second) { diff --git a/app/src/main/res/color/text_input_layout_color.xml b/app/src/main/res/color/text_input_layout_color.xml new file mode 100644 index 00000000..fcd5fa09 --- /dev/null +++ b/app/src/main/res/color/text_input_layout_color.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="true" android:color="@color/accent"/> + <item android:state_hovered="true" android:color="@color/accent"/> + <item android:state_focused="true" android:color="@color/accent"/> + <item android:color="@color/grey600" /> +</selector> diff --git a/app/src/main/res/drawable/bg_navdrawer_item.xml b/app/src/main/res/drawable/bg_navdrawer_item.xml index a366c0d2..008b2abb 100644 --- a/app/src/main/res/drawable/bg_navdrawer_item.xml +++ b/app/src/main/res/drawable/bg_navdrawer_item.xml @@ -10,7 +10,7 @@ <shape android:shape="rectangle"> <!-- value of color is irrelevant, but solid needs to be defined for mask to work --> <solid android:color="@color/bg_highlighted" /> - <corners android:radius="@dimen/spacer_1hx" /> + <corners android:radius="@dimen/spacer_5x" /> </shape> </item> @@ -21,14 +21,14 @@ <selector> <item android:state_selected="true"> <shape android:shape="rectangle"> - <corners android:radius="@dimen/spacer_1hx" /> + <corners android:radius="@dimen/spacer_5x" /> <solid android:color="@color/bg_highlighted" /> </shape> </item> <item> <shape android:shape="rectangle"> - <corners android:radius="@dimen/spacer_1hx" /> + <corners android:radius="@dimen/spacer_5x" /> </shape> </item> </selector> diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index aebbea0f..89c2aaa6 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -4,6 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="?attr/colorPrimary" android:orientation="vertical"> <com.google.android.material.appbar.AppBarLayout @@ -15,8 +16,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" app:titleMarginStart="0dp" @@ -27,7 +27,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" - app:tabIndicatorColor="@color/defaultBrand" /> + app:tabMode="fixed" /> </com.google.android.material.appbar.AppBarLayout> <androidx.viewpager2.widget.ViewPager2 @@ -35,7 +35,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" - android:paddingStart="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x" /> + android:paddingHorizontal="@dimen/spacer_1x" /> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit.xml b/app/src/main/res/layout/activity_edit.xml index 1fcff7ca..8948c076 100644 --- a/app/src/main/res/layout/activity_edit.xml +++ b/app/src/main/res/layout/activity_edit.xml @@ -15,8 +15,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" app:titleMarginStart="0dp" diff --git a/app/src/main/res/layout/activity_exception.xml b/app/src/main/res/layout/activity_exception.xml index f275a703..ce352cc6 100644 --- a/app/src/main/res/layout/activity_exception.xml +++ b/app/src/main/res/layout/activity_exception.xml @@ -11,8 +11,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:elevation="4dp" app:titleMarginStart="0dp" @@ -56,8 +55,7 @@ <HorizontalScrollView android:layout_width="match_parent" android:layout_height="0dp" - android:layout_marginStart="@dimen/spacer_2x" - android:layout_marginEnd="@dimen/spacer_2x" + android:layout_marginHorizontal="@dimen/spacer_2x" android:layout_weight="1"> <TextView @@ -74,7 +72,6 @@ </ScrollView> <LinearLayout - style="?android:buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/spacer_2x" @@ -84,7 +81,7 @@ <Button android:id="@+id/close" - style="?android:buttonBarButtonStyle" + style="@style/Widget.Material3.Button.TextButton" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight=".5" @@ -93,16 +90,13 @@ <Button android:id="@+id/copy" - style="?android:buttonBarButtonStyle" + style="@style/Widget.Material3.Button" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_marginTop="6dp" - android:layout_marginBottom="6dp" + android:layout_marginVertical="6dp" android:layout_weight=".5" - android:background="@color/defaultBrand" - android:foreground="?attr/selectableItemBackground" android:text="@string/simple_copy" - android:textColor="@color/fg_contrast" + app:backgroundTint="@color/defaultBrand" tools:ignore="UnusedAttribute" /> </LinearLayout> diff --git a/app/src/main/res/layout/activity_formatting_help.xml b/app/src/main/res/layout/activity_formatting_help.xml index 8f3c0ae8..99dbb182 100644 --- a/app/src/main/res/layout/activity_formatting_help.xml +++ b/app/src/main/res/layout/activity_formatting_help.xml @@ -16,8 +16,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" app:title="@string/action_formatting_help" @@ -34,8 +33,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" android:orientation="vertical" android:padding="@dimen/spacer_2x"> @@ -46,7 +44,6 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/fg_default" android:textIsSelectable="true" - android:theme="@style/textViewStyle" tools:maxLength="200" tools:text="@tools:sample/lorem/random" /> @@ -66,7 +63,6 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/fg_default" android:textIsSelectable="true" - android:theme="@style/textViewStyle" tools:maxLength="300" tools:text="@tools:sample/lorem/random" /> diff --git a/app/src/main/res/layout/activity_import_account.xml b/app/src/main/res/layout/activity_import_account.xml index 7484a61b..630990e2 100644 --- a/app/src/main/res/layout/activity_import_account.xml +++ b/app/src/main/res/layout/activity_import_account.xml @@ -38,15 +38,13 @@ <Button android:id="@+id/add_button" - style="@style/Widget.AppCompat.Button.Colored" + style="@style/Widget.Material3.Button.ElevatedButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/welcome_text" android:layout_centerHorizontal="true" - android:paddingStart="32dp" - android:paddingTop="24dp" - android:paddingEnd="32dp" - android:paddingBottom="24dp" + android:paddingHorizontal="32dp" + android:paddingVertical="@dimen/spacer_3x" android:text="@string/choose_account" app:backgroundTint="@color/defaultBrand" /> diff --git a/app/src/main/res/layout/activity_manage_accounts.xml b/app/src/main/res/layout/activity_manage_accounts.xml index 7e01326b..17cd73cc 100644 --- a/app/src/main/res/layout/activity_manage_accounts.xml +++ b/app/src/main/res/layout/activity_manage_accounts.xml @@ -16,8 +16,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" app:title="@string/manage_accounts" diff --git a/app/src/main/res/layout/activity_notes_list_view.xml b/app/src/main/res/layout/activity_notes_list_view.xml index 858c3a91..87d7af90 100644 --- a/app/src/main/res/layout/activity_notes_list_view.xml +++ b/app/src/main/res/layout/activity_notes_list_view.xml @@ -24,10 +24,8 @@ <com.google.android.material.card.MaterialCardView android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginTop="@dimen/spacer_1hx" - android:layout_marginEnd="@dimen/spacer_activity_sides" - android:layout_marginBottom="@dimen/spacer_1hx" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" + android:layout_marginVertical="@dimen/spacer_1hx" app:cardBackgroundColor="@color/appbar" app:cardCornerRadius="@dimen/spacer_4x" app:cardElevation="2dp" @@ -59,14 +57,14 @@ <androidx.appcompat.widget.AppCompatImageView android:id="@+id/sorting_method" - android:layout_width="?attr/actionBarSize" - android:layout_height="?attr/actionBarSize" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="center_vertical|end" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/action_sorting_method" android:padding="@dimen/spacer_2x" android:tint="?attr/colorAccent" - android:translationX="@dimen/spacer_1x" + android:translationX="@dimen/spacer_2x" app:srcCompat="@drawable/alphabetical_asc" /> <androidx.appcompat.widget.AppCompatImageView @@ -75,7 +73,7 @@ android:layout_height="?attr/actionBarSize" android:layout_gravity="center_vertical|end" android:background="?attr/selectableItemBackgroundBorderless" - android:padding="12dp" + android:paddingVertical="@dimen/spacer_2x" android:tooltipText="@string/manage_accounts" app:srcCompat="@drawable/ic_account_circle_grey_24dp" tools:targetApi="o" /> @@ -88,8 +86,7 @@ android:id="@+id/search_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" android:visibility="gone" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" @@ -139,7 +136,11 @@ <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab_create" - style="@style/fab" + style="?attr/floatingActionButtonPrimaryStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="end|bottom" + android:layout_margin="@dimen/spacer_2x" android:contentDescription="@string/action_create" android:title="@string/action_create" app:backgroundTint="@color/defaultBrand" diff --git a/app/src/main/res/layout/activity_preferences.xml b/app/src/main/res/layout/activity_preferences.xml index 77f9ff03..ec4cce0c 100644 --- a/app/src/main/res/layout/activity_preferences.xml +++ b/app/src/main/res/layout/activity_preferences.xml @@ -14,8 +14,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" app:contentInsetStartWithNavigation="0dp" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" app:title="@string/action_settings" diff --git a/app/src/main/res/layout/dialog_account_switcher.xml b/app/src/main/res/layout/dialog_account_switcher.xml index 8e8634b2..f75d0f20 100644 --- a/app/src/main/res/layout/dialog_account_switcher.xml +++ b/app/src/main/res/layout/dialog_account_switcher.xml @@ -6,7 +6,6 @@ android:layout_height="wrap_content" android:orientation="vertical"> - <LinearLayout android:id="@+id/accountLayout" android:layout_width="match_parent" @@ -15,8 +14,7 @@ android:gravity="center_vertical" android:orientation="horizontal" android:padding="@dimen/spacer_2x" - android:paddingStart="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x"> + android:paddingHorizontal="@dimen/spacer_1x"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/currentAccountItemAvatar" @@ -28,7 +26,6 @@ android:scaleType="center" app:srcCompat="@drawable/ic_account_circle_grey_24dp" /> - <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" @@ -83,7 +80,6 @@ tools:itemCount="3" tools:listitem="@layout/item_account_choose" /> - <LinearLayout android:id="@+id/add_account" android:layout_width="match_parent" @@ -111,7 +107,6 @@ android:text="@string/add_account" android:textAppearance="@style/TextAppearance.AppCompat.Widget.TextView.SpinnerItem" android:textColor="?android:textColorPrimary" /> - </LinearLayout> <LinearLayout diff --git a/app/src/main/res/layout/dialog_change_category.xml b/app/src/main/res/layout/dialog_change_category.xml index 86243c23..bdd19c88 100644 --- a/app/src/main/res/layout/dialog_change_category.xml +++ b/app/src/main/res/layout/dialog_change_category.xml @@ -8,13 +8,27 @@ android:orientation="vertical" android:padding="?attr/dialogPreferredPadding"> - <EditText - android:id="@+id/search" + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/inputWrapper" + style="@style/textInputLayoutStyle" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/spacer_1x" android:hint="@string/change_category_title" - android:importantForAutofill="no" - android:inputType="text" /> + android:labelFor="@id/search"> + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/search" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:imeOptions="actionDone" + android:importantForAutofill="no" + android:inputType="text"> + + <requestFocus /> + </com.google.android.material.textfield.TextInputEditText> + </com.google.android.material.textfield.TextInputLayout> + <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" diff --git a/app/src/main/res/layout/dialog_edit_setting.xml b/app/src/main/res/layout/dialog_edit_setting.xml new file mode 100644 index 00000000..d2ed4789 --- /dev/null +++ b/app/src/main/res/layout/dialog_edit_setting.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.progressindicator.LinearProgressIndicator + android:id="@+id/progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:indeterminate="true" + android:paddingHorizontal="?attr/dialogPreferredPadding" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/inputWrapper" + style="@style/textInputLayoutStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/change_note_title" + android:padding="?attr/dialogPreferredPadding" + android:visibility="invisible" + tools:visibility="visible"> + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/property" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:imeOptions="actionDone" + android:importantForAutofill="no" + android:inputType="text"> + + <requestFocus /> + </com.google.android.material.textfield.TextInputEditText> + + </com.google.android.material.textfield.TextInputLayout> +</FrameLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/dialog_edit_title.xml b/app/src/main/res/layout/dialog_edit_title.xml index 805926bd..5e744c99 100644 --- a/app/src/main/res/layout/dialog_edit_title.xml +++ b/app/src/main/res/layout/dialog_edit_title.xml @@ -1,14 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> <com.google.android.material.textfield.TextInputLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/inputWrapper" + style="@style/textInputLayoutStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="16dp"> + android:hint="@string/change_note_title" + android:padding="?attr/dialogPreferredPadding"> - <EditText + <com.google.android.material.textfield.TextInputEditText android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/change_note_title" + android:imeOptions="actionDone" android:importantForAutofill="no" - android:inputType="text" /> + android:inputType="text"> + + <requestFocus /> + </com.google.android.material.textfield.TextInputEditText> + </com.google.android.material.textfield.TextInputLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/dialog_exception.xml b/app/src/main/res/layout/dialog_exception.xml index 88a2495f..450ade9d 100644 --- a/app/src/main/res/layout/dialog_exception.xml +++ b/app/src/main/res/layout/dialog_exception.xml @@ -31,8 +31,7 @@ android:id="@+id/stacktrace" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_marginTop="@dimen/spacer_2x" - android:layout_marginBottom="@dimen/spacer_2x" + android:layout_marginVertical="@dimen/spacer_2x" android:layout_weight="1" android:background="@color/bg_highlighted" android:padding="@dimen/spacer_1x" diff --git a/app/src/main/res/layout/drawer_layout.xml b/app/src/main/res/layout/drawer_layout.xml index 7ad83d80..0b868cec 100644 --- a/app/src/main/res/layout/drawer_layout.xml +++ b/app/src/main/res/layout/drawer_layout.xml @@ -63,8 +63,7 @@ android:id="@+id/navigationList" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="@dimen/spacer_1x" - android:paddingBottom="@dimen/spacer_1x" + android:paddingVertical="@dimen/spacer_1x" app:layoutManager="LinearLayoutManager" tools:itemCount="6" tools:listitem="@layout/item_navigation" /> @@ -73,8 +72,7 @@ android:id="@+id/navigationMenu" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="@dimen/spacer_1x" - android:paddingBottom="@dimen/spacer_1x" + android:paddingVertical="@dimen/spacer_1x" app:layoutManager="LinearLayoutManager" tools:itemCount="3" tools:listitem="@layout/item_navigation" /> diff --git a/app/src/main/res/layout/fragment_about_credits_tab.xml b/app/src/main/res/layout/fragment_about_credits_tab.xml index 35dcae9f..fad03f62 100644 --- a/app/src/main/res/layout/fragment_about_credits_tab.xml +++ b/app/src/main/res/layout/fragment_about_credits_tab.xml @@ -14,8 +14,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:layout_marginTop="30dp" - android:layout_marginBottom="30dp" + android:layout_marginVertical="30dp" android:text="@string/app_name" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/fg_default_low" diff --git a/app/src/main/res/layout/fragment_about_license_tab.xml b/app/src/main/res/layout/fragment_about_license_tab.xml index 24e6163f..9e425d4e 100644 --- a/app/src/main/res/layout/fragment_about_license_tab.xml +++ b/app/src/main/res/layout/fragment_about_license_tab.xml @@ -25,7 +25,7 @@ <com.google.android.material.button.MaterialButton android:id="@+id/about_app_license_button" - style="@style/Widget.MaterialComponents.Button" + style="@style/Widget.Material3.Button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/about_app_license_button" diff --git a/app/src/main/res/layout/fragment_note_edit.xml b/app/src/main/res/layout/fragment_note_edit.xml index c377998c..75e6ab84 100644 --- a/app/src/main/res/layout/fragment_note_edit.xml +++ b/app/src/main/res/layout/fragment_note_edit.xml @@ -27,41 +27,41 @@ android:id="@+id/editContent" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" android:background="?attr/colorPrimary" android:ems="10" android:gravity="top" android:inputType="textMultiLine|textCapSentences" android:lineSpacingMultiplier="@dimen/note_line_spacing" android:padding="@dimen/spacer_2x" - android:paddingStart="@dimen/spacer_2x" - android:paddingEnd="@dimen/spacer_2x" android:textColor="@color/fg_default" - android:theme="@style/textViewStyle" tools:text="@tools:sample/lorem/random" /> </ScrollView> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/searchPrev" - style="@style/fab" + style="?attr/floatingActionButtonSmallSecondaryStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="bottom|end" + android:layout_margin="@dimen/spacer_2x" android:contentDescription="@string/simple_prev" android:translationY="-56dp" android:visibility="gone" app:backgroundTint="@color/defaultBrand" - app:fabSize="mini" app:srcCompat="@drawable/ic_keyboard_arrow_up_white_24dp" tools:visibility="visible" /> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/searchNext" - style="@style/fab" + style="?attr/floatingActionButtonSmallSecondaryStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="bottom|end" + android:layout_margin="@dimen/spacer_2x" android:contentDescription="@string/simple_next" android:visibility="gone" app:backgroundTint="@color/defaultBrand" - app:fabSize="mini" app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" tools:visibility="visible" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_note_preview.xml b/app/src/main/res/layout/fragment_note_preview.xml index 0b660f8d..bd9aabef 100644 --- a/app/src/main/res/layout/fragment_note_preview.xml +++ b/app/src/main/res/layout/fragment_note_preview.xml @@ -24,40 +24,41 @@ android:id="@+id/single_note_content" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_activity_sides" - android:layout_marginEnd="@dimen/spacer_activity_sides" + android:layout_marginHorizontal="@dimen/spacer_activity_sides" android:lineSpacingMultiplier="@dimen/note_line_spacing" android:padding="@dimen/spacer_2x" - android:paddingStart="@dimen/spacer_2x" - android:paddingEnd="@dimen/spacer_2x" + android:paddingHorizontal="@dimen/spacer_2x" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/fg_default" android:textIsSelectable="true" - android:theme="@style/textViewStyle" tools:text="@tools:sample/lorem/random" /> </ScrollView> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/searchPrev" - style="@style/fab" + style="?attr/floatingActionButtonSmallSecondaryStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="bottom|end" + android:layout_margin="@dimen/spacer_2x" android:contentDescription="@string/simple_prev" android:translationY="-56dp" android:visibility="gone" app:backgroundTint="@color/defaultBrand" - app:fabSize="mini" app:srcCompat="@drawable/ic_keyboard_arrow_up_white_24dp" tools:visibility="visible" /> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/searchNext" - style="@style/fab" + style="?attr/floatingActionButtonSmallSecondaryStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_gravity="bottom|end" + android:layout_margin="@dimen/spacer_2x" android:contentDescription="@string/simple_next" android:visibility="gone" app:backgroundTint="@color/defaultBrand" - app:fabSize="mini" app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" tools:visibility="visible" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_account_choose.xml b/app/src/main/res/layout/item_account_choose.xml index 8cfbd4be..30458288 100644 --- a/app/src/main/res/layout/item_account_choose.xml +++ b/app/src/main/res/layout/item_account_choose.xml @@ -8,8 +8,7 @@ android:gravity="center" android:orientation="horizontal" android:padding="@dimen/spacer_2x" - android:paddingStart="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x"> + android:paddingHorizontal="@dimen/spacer_1x"> <FrameLayout android:layout_width="wrap_content" diff --git a/app/src/main/res/layout/item_notes_list_note_item_grid.xml b/app/src/main/res/layout/item_notes_list_note_item_grid.xml index 7f26b263..d9325f19 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_grid.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_grid.xml @@ -21,15 +21,13 @@ android:id="@+id/noteTitle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_2x" + android:layout_marginHorizontal="@dimen/spacer_2x" android:layout_marginTop="@dimen/spacer_2x" - android:layout_marginEnd="@dimen/spacer_2x" android:layout_marginBottom="@dimen/spacer_1x" android:hyphenationFrequency="full" android:textAppearance="?attr/textAppearanceHeadline5" android:textColor="@color/fg_default" tools:maxLength="50" - tools:targetApi="m" tools:text="@tools:sample/lorem/random" /> @@ -37,8 +35,7 @@ android:id="@+id/noteExcerpt" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacer_2x" - android:layout_marginEnd="@dimen/spacer_2x" + android:layout_marginHorizontal="@dimen/spacer_2x" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/fg_default" tools:maxLength="200" diff --git a/app/src/main/res/layout/item_notes_list_note_item_grid_only_title.xml b/app/src/main/res/layout/item_notes_list_note_item_grid_only_title.xml index 9e7d0f3b..f60e5292 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_grid_only_title.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_grid_only_title.xml @@ -55,7 +55,6 @@ android:textAppearance="?attr/textAppearanceHeadline5" android:textColor="@color/fg_default" tools:maxLength="50" - tools:targetApi="m" tools:text="@tools:sample/lorem/random" /> </LinearLayout> </com.google.android.material.card.MaterialCardView>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_notes_list_note_item_with_excerpt.xml b/app/src/main/res/layout/item_notes_list_note_item_with_excerpt.xml index 966f4b66..384a674b 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_with_excerpt.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_with_excerpt.xml @@ -65,9 +65,8 @@ android:layout_weight="1" android:orientation="vertical" android:paddingStart="0dp" - android:paddingTop="@dimen/spacer_2x" - android:paddingEnd="@dimen/spacer_2x" - android:paddingBottom="@dimen/spacer_2x"> + android:paddingVertical="@dimen/spacer_2x" + android:paddingEnd="@dimen/spacer_2x"> <LinearLayout android:layout_width="match_parent" @@ -97,8 +96,7 @@ android:layout_weight="1" android:ellipsize="end" android:maxLines="1" - android:paddingTop="1dp" - android:paddingBottom="1dp" + android:paddingVertical="1dp" android:textSize="@dimen/secondary_font_size" tools:text="@tools:sample/lorem/random" /> @@ -109,10 +107,8 @@ android:layout_marginStart="@dimen/spacer_1x" android:background="@drawable/border" android:maxLines="1" - android:paddingStart="@dimen/spacer_1x" - android:paddingTop="1dp" - android:paddingEnd="@dimen/spacer_1x" - android:paddingBottom="1dp" + android:paddingVertical="1dp" + android:paddingHorizontal="@dimen/spacer_1x" android:singleLine="true" android:textColor="?android:textColorPrimary" android:textSize="@dimen/secondary_font_size" diff --git a/app/src/main/res/layout/item_notes_list_note_item_without_excerpt.xml b/app/src/main/res/layout/item_notes_list_note_item_without_excerpt.xml index 91232a01..f7e42863 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_without_excerpt.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_without_excerpt.xml @@ -63,13 +63,11 @@ android:id="@+id/noteTitle" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="10sp" - android:layout_marginBottom="10sp" + android:layout_marginVertical="10sp" android:layout_weight="1" android:ellipsize="end" android:maxLines="1" - android:paddingTop="@dimen/spacer_2x" - android:paddingBottom="@dimen/spacer_2x" + android:paddingVertical="@dimen/spacer_2x" android:textColor="?android:textColorPrimary" android:textSize="@dimen/primary_font_size" tools:text="@tools:sample/lorem/random" /> @@ -83,8 +81,7 @@ android:layout_marginEnd="@dimen/spacer_2x" android:background="@drawable/border" android:maxLines="1" - android:paddingStart="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x" + android:paddingHorizontal="@dimen/spacer_1x" android:paddingBottom="1dp" android:singleLine="true" android:textColor="?android:textColorPrimary" diff --git a/app/src/main/res/layout/item_pref.xml b/app/src/main/res/layout/item_pref.xml index 1d84737b..82295748 100644 --- a/app/src/main/res/layout/item_pref.xml +++ b/app/src/main/res/layout/item_pref.xml @@ -4,8 +4,7 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" - android:paddingStart="@dimen/spacer_activity_sides" - android:paddingEnd="@dimen/spacer_activity_sides" + android:paddingHorizontal="@dimen/spacer_activity_sides" android:minHeight="?android:attr/listPreferredItemHeight"> <ImageView diff --git a/app/src/main/res/layout/item_tip.xml b/app/src/main/res/layout/item_tip.xml index 2177d013..96696725 100644 --- a/app/src/main/res/layout/item_tip.xml +++ b/app/src/main/res/layout/item_tip.xml @@ -5,8 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingTop="@dimen/spacer_1x" - android:paddingBottom="@dimen/spacer_1x"> + android:paddingVertical="@dimen/spacer_1x"> <TextView android:id="@+id/tip" diff --git a/app/src/main/res/layout/widget_entry.xml b/app/src/main/res/layout/widget_entry.xml index 460a255b..25f763f4 100644 --- a/app/src/main/res/layout/widget_entry.xml +++ b/app/src/main/res/layout/widget_entry.xml @@ -6,10 +6,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingTop="@dimen/spacer_1x" + android:paddingVertical="@dimen/spacer_1x" android:paddingStart="@null" - android:paddingEnd="@dimen/spacer_1hx" - android:paddingBottom="@dimen/spacer_1x"> + android:paddingEnd="@dimen/spacer_1hx"> <ImageView android:id="@+id/widget_entry_fav_icon" diff --git a/app/src/main/res/layout/widget_entry_add.xml b/app/src/main/res/layout/widget_entry_add.xml index 0c7787e7..901096b6 100644 --- a/app/src/main/res/layout/widget_entry_add.xml +++ b/app/src/main/res/layout/widget_entry_add.xml @@ -31,8 +31,7 @@ android:layout_gravity="center_vertical" android:contentDescription="@string/widget_entry_fav_contentDescription" android:foregroundGravity="center_vertical" - android:paddingStart="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x" + android:paddingHorizontal="@dimen/spacer_1x" android:paddingBottom="@dimen/spacer_1x" app:srcCompat="@drawable/ic_add_blue_24dp" /> </LinearLayout> diff --git a/app/src/main/res/layout/widget_note_list.xml b/app/src/main/res/layout/widget_note_list.xml index a3e7e163..a34f14cd 100644 --- a/app/src/main/res/layout/widget_note_list.xml +++ b/app/src/main/res/layout/widget_note_list.xml @@ -5,10 +5,8 @@ android:layout_height="match_parent" android:background="@drawable/widget_background" android:orientation="vertical" - android:paddingStart="@dimen/widget_inner_padding_horizontal" - android:paddingTop="@dimen/widget_inner_padding_vertical" - android:paddingEnd="@dimen/widget_inner_padding_horizontal" - android:paddingBottom="@dimen/widget_inner_padding_vertical"> + android:paddingVertical="@dimen/widget_inner_padding_vertical" + android:paddingHorizontal="@dimen/widget_inner_padding_horizontal"> <ListView android:id="@+id/note_list_widget_lv" diff --git a/app/src/main/res/layout/widget_single_note.xml b/app/src/main/res/layout/widget_single_note.xml index 053a059d..ac137083 100644 --- a/app/src/main/res/layout/widget_single_note.xml +++ b/app/src/main/res/layout/widget_single_note.xml @@ -9,10 +9,8 @@ android:id="@+id/single_note_widget_lv" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingStart="@dimen/widget_inner_padding_horizontal" - android:paddingTop="@dimen/widget_inner_padding_vertical" - android:paddingEnd="@dimen/widget_inner_padding_horizontal" - android:paddingBottom="@dimen/widget_inner_padding_vertical" + android:paddingVertical="@dimen/widget_inner_padding_vertical" + android:paddingHorizontal="@dimen/widget_inner_padding_horizontal" tools:listitem="@layout/widget_single_note_content" /> <TextView diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 87944d9d..4e33728d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,6 +4,7 @@ <color name="primary">#ffffff</color> <color name="accent">#121212</color> + <color name="danger">#d40000</color> <color name="defaultBrand">#0082C9</color> @@ -21,7 +22,8 @@ <color name="fg_secondary">#999999</color> <color name="fg_contrast">#ffffff</color> - <color name="icon_color_default">#757575</color> + <color name="grey600">#757575</color> + <color name="icon_color_default">@color/grey600</color> <color name="category_background">@color/bg_normal</color> <color name="category_border">@color/defaultBrand</color> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c3f28846..661bcfd2 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,39 +1,82 @@ <?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <style name="BaseTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge"> + <style name="BaseTheme" parent="Theme.Material3.DayNight.NoActionBar"> <item name="colorPrimary">@color/primary</item> + <item name="colorPrimaryDark">?android:colorPrimary</item> <item name="colorAccent">@color/accent</item> - <item name="android:actionModeBackground">?attr/colorPrimary</item> - <item name="colorControlNormal">?attr/colorAccent</item> - <item name="windowActionModeOverlay">true</item> - <item name="actionModeStyle">@style/actionModeStyle</item> - <item name="toolbarStyle">@style/toolbarStyle</item> + <item name="android:statusBarColor">?attr/colorPrimary</item> <item name="android:windowLightStatusBar">@bool/isDayMode</item> + <item name="android:colorControlNormal">?attr/colorAccent</item> + <item name="android:colorControlActivated">?attr/colorAccent</item> + <item name="android:textColorLink">?android:colorAccent</item> + <item name="android:textColorHighlight">@color/defaultTextHighlightBackground</item> + <item name="windowActionModeOverlay">true</item> + <item name="android:actionModeBackground">?attr/colorPrimary</item> + + <!-- Workaround: Preferences Dialogs are using AlertDialogs instead of MaterialAlertDialogs. --> + <!-- https://stackoverflow.com/questions/70650073/adjust-androidx-preference-dialogs-to-follow-material-you --> + <item name="alertDialogTheme">@style/PreferencesAlertDialogTheme</item> + + <item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item> + + <item name="toolbarStyle">@style/toolbarStyle</item> + <item name="actionModeStyle">@style/actionModeStyle</item> + <item name="tabStyle">@style/tabStyle</item> </style> <style name="AppTheme" parent="BaseTheme" /> - <style name="textViewStyle"> - <item name="colorAccent">@color/cursorHandles</item> - <item name="android:textColorHighlight">@color/defaultTextHighlightBackground</item> + <style name="toolbarStyle" parent="Widget.Material3.Toolbar"> + <item name="popupTheme">@style/PopupTheme</item> </style> - <style name="toolbarStyle" parent="@style/Widget.AppCompat.Toolbar"> - <item name="android:background">?attr/colorPrimary</item> + <style name="PopupTheme" parent="Theme.Material3.DayNight"> + <item name="colorPrimary">@color/primary</item> + <item name="checkboxStyle">@style/checkboxStyle</item> + </style> + + <style name="checkboxStyle" parent="Widget.Material3.CompoundButton.CheckBox"> + <item name="materialThemeOverlay">@style/materialThemeOverlay</item> </style> - <style name="actionModeStyle" parent="@style/Widget.AppCompat.ActionMode"> + <style name="materialThemeOverlay" parent="Widget.Material3.CompoundButton.CheckBox"> + <item name="colorPrimary">@color/accent</item> + </style> + + <style name="actionModeStyle" parent="@style/Widget.Material3.ActionMode"> <item name="android:paddingStart">@dimen/spacer_activity_sides</item> <item name="android:paddingEnd">@dimen/spacer_activity_sides</item> </style> - <style name="fab"> - <item name="android:layout_margin">16dp</item> - <item name="android:layout_width">wrap_content</item> - <item name="android:layout_height">wrap_content</item> - <item name="android:layout_gravity">end|bottom</item> + <style name="tabStyle" parent="Widget.Material3.TabLayout"> + <item name="backgroundColor">@android:color/transparent</item> + <item name="itemBackground">@android:color/transparent</item> + <item name="tabIndicatorColor">@android:color/transparent</item> + <item name="tabTextColor">?attr/colorAccent</item> + <item name="tabIconTint">?attr/colorAccent</item> + </style> + + <style name="textInputLayoutStyle" parent="Widget.Material3.TextInputLayout.OutlinedBox.Dense"> + <item name="boxStrokeColor">@color/text_input_layout_color</item> + <item name="hintTextColor">@color/text_input_layout_color</item> + </style> + + <style name="MaterialAlertDialogTheme" parent="ThemeOverlay.Material3.MaterialAlertDialog"> + <item name="buttonBarPositiveButtonStyle">@style/buttonStyle</item> + <item name="buttonBarNegativeButtonStyle">@style/buttonStyle</item> + <item name="buttonBarNeutralButtonStyle">@style/buttonStyle</item> + </style> + + <style name="PreferencesAlertDialogTheme" parent="MaterialAlertDialogTheme"> + <!-- https://m3.material.io/components/dialogs/specs#6771d107-624e-47cc-b6d8-2b7b620ba2f1 --> + <item name="dialogCornerRadius">28dp</item> + <item name="android:background">?attr/colorSurface</item> + </style> + + <style name="buttonStyle" parent="Widget.Material3.Button.TextButton.Dialog"> + <item name="android:textColor">?attr/colorAccent</item> </style> <style name="Theme.App.Starting" parent="Theme.SplashScreen"> diff --git a/fastlane/metadata/android/en-US/changelogs/3007000.txt b/fastlane/metadata/android/en-US/changelogs/3007000.txt new file mode 100644 index 00000000..c53e3771 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/3007000.txt @@ -0,0 +1,3 @@ +- ✨ Material 3 Theme (#1330) +- 🐞 Fix missing keyboard when changing account settings (#916) +- 🌎 Updated translations
\ No newline at end of file |