From 851453e788404e4275809f34f199d0c3023ca4ea Mon Sep 17 00:00:00 2001 From: Soren Stoutner <soren@stoutner.com> Date: Wed, 14 Dec 2022 12:36:26 -0700 Subject: [PATCH] Don't replace a high resolution favorite icon with a lower resolution one. https://redmine.stoutner.com/issues/947 --- .../activities/MainWebViewActivity.java | 18 +++++----- .../dialogs/PinnedMismatchDialog.kt | 2 +- .../views/NestedScrollWebView.kt | 35 ++++++++++++------- app/src/main/res/values-fr/strings.xml | 30 ++++++++-------- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 649cf644..0f412f01 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1870,7 +1870,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } else if (menuItemId == R.id.add_to_homescreen) { // Add to homescreen. // Instantiate the create home screen shortcut dialog. DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), currentWebView.getUrl(), - currentWebView.getFavoriteOrDefaultIcon()); + currentWebView.getFavoriteIcon()); // Show the create home screen shortcut dialog. createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut)); @@ -3124,7 +3124,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onTabReselected(TabLayout.Tab tab) { // Instantiate the View SSL Certificate dialog. - DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteOrDefaultIcon()); + DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteIcon()); // Display the View SSL Certificate dialog. viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate)); @@ -3140,7 +3140,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the launch bookmarks activity FAB to launch the bookmarks activity. launchBookmarksActivityFab.setOnClickListener(v -> { // Get a copy of the favorite icon bitmap. - Bitmap favoriteIconBitmap = currentWebView.getFavoriteOrDefaultIcon(); + Bitmap favoriteIconBitmap = currentWebView.getFavoriteIcon(); // Create a favorite icon byte array output stream. ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream(); @@ -3167,7 +3167,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the create new bookmark folder FAB to display an alert dialog. createBookmarkFolderFab.setOnClickListener(v -> { // Create a create bookmark folder dialog. - DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteOrDefaultIcon()); + DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteIcon()); // Show the create bookmark folder dialog. createBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.create_folder)); @@ -3176,7 +3176,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the create new bookmark FAB to display an alert dialog. createBookmarkFab.setOnClickListener(view -> { // Instantiate the create bookmark dialog. - DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteOrDefaultIcon()); + DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteIcon()); // Display the create bookmark dialog. createBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.create_bookmark)); @@ -3599,7 +3599,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook TextView tabTitleTextView = tabCustomView.findViewById(R.id.title_textview); // Set the default favorite icon as the favorite icon for this tab. - tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true)); + tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteIcon(), 64, 64, true)); // Set the loading title text. tabTitleTextView.setText(R.string.loading); @@ -5232,10 +5232,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the favorite icon when it changes. @Override public void onReceivedIcon(WebView view, Bitmap icon) { - // Only update the favorite icon if the website has finished loading. - if (progressBar.getVisibility() == View.GONE) { + // Only update the favorite icon if the website has finished loading and the new favorite icon height is greater than the current favorite icon height. This prevents low resolution icons from replacing high resolution one. + if ((progressBar.getVisibility() == View.GONE) && (icon.getHeight() > nestedScrollWebView.getFavoriteIconHeight())) { // Store the new favorite icon. - nestedScrollWebView.setFavoriteOrDefaultIcon(icon); + nestedScrollWebView.setFavoriteIcon(icon); // Get the current page position. int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId()); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.kt b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.kt index b3f6de21..97cd63d0 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.kt +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.kt @@ -102,7 +102,7 @@ class PinnedMismatchDialog : DialogFragment() { val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog) // Get the favorite icon. - val favoriteIconBitmap = nestedScrollWebView.getFavoriteOrDefaultIcon() + val favoriteIconBitmap = nestedScrollWebView.getFavoriteIcon() // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21. val defaultFavoriteIconDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.world) diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.kt b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.kt index ad34be83..eafe10fe 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.kt +++ b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2019-2022 Soren Stoutner <soren@stoutner.com>. + * Copyright 2019-2022 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>. * @@ -31,7 +31,7 @@ import android.webkit.HttpAuthHandler import android.webkit.SslErrorHandler import android.webkit.WebView -import androidx.core.content.ContextCompat +import androidx.appcompat.content.res.AppCompatResources.getDrawable import androidx.core.view.NestedScrollingChild2 import androidx.core.view.NestedScrollingChildHelper import androidx.core.view.ViewCompat @@ -117,7 +117,8 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS // Define the private variables. private val nestedScrollingChildHelper: NestedScrollingChildHelper = NestedScrollingChildHelper(this) - private lateinit var favoriteOrDefaultIcon: Bitmap + private lateinit var favoriteIcon: Bitmap + private var favoriteIconHeight = 0 private var previousYPosition = 0 // The previous Y position needs to be tracked between motion events. private var hasPinnedSslCertificate = false private var pinnedSslIssuedToCName = "" @@ -149,19 +150,25 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS // Favorite or default icon. fun initializeFavoriteIcon() { - // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21. - val favoriteIconDrawable = ContextCompat.getDrawable(context, R.drawable.world) + // Get the default favorite icon drawable. + val favoriteIconDrawable = getDrawable(context, R.drawable.world) // Cast the favorite icon drawable to a bitmap drawable. val favoriteIconBitmapDrawable = (favoriteIconDrawable as BitmapDrawable?)!! // Store the default icon bitmap. - favoriteOrDefaultIcon = favoriteIconBitmapDrawable.bitmap + favoriteIcon = favoriteIconBitmapDrawable.bitmap + + // Set the favorite icon height to be 0. This way any favorite icons presented by the website will overwrite it. + favoriteIconHeight = 0 } - fun setFavoriteOrDefaultIcon(icon: Bitmap) { + fun setFavoriteIcon(icon: Bitmap) { + // Store the current favorite icon height. + favoriteIconHeight = icon.height + // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation. - favoriteOrDefaultIcon = if (icon.height > 256 || icon.width > 256) { + favoriteIcon = if (icon.height > 256 || icon.width > 256) { Bitmap.createScaledBitmap(icon, 256, 256, true) } else { // Store the icon as presented. @@ -169,11 +176,15 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS } } - fun getFavoriteOrDefaultIcon(): Bitmap { - // Return the favorite or default icon. This is the only way to return a non-nullable variable while retaining the custom initialization and setter functions above. - return favoriteOrDefaultIcon + fun getFavoriteIcon(): Bitmap { + // Return the favorite icon. This is the only way to return a non-nullable variable while retaining the custom initialization and setter functions above. + return favoriteIcon } + fun getFavoriteIconHeight(): Int { + // Return the favorite icon height. + return favoriteIconHeight + } // Reset the handlers. fun resetSslErrorHandler() { @@ -540,4 +551,4 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS // Dispatch a nested fling with the specified velocity. return nestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed) } -} \ No newline at end of file +} diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 476012b1..b7aba539 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -43,7 +43,8 @@ <string name="form_data_deleted">Données de formulaires supprimées</string> <string name="open_navigation_drawer">Ouvrir le panneau de navigation</string> <string name="close_navigation_drawer">Fermer le panneau de navigation</string> - <string name="unrecognized_url">URL inconnue:</string> + <string name="pin_drawer">Ãpingler le panneau</string> + <string name="unrecognized_url">URL inconnue :</string> <string name="add_tab">Ajouter un onglet</string> <string name="close_tab">Fermer l\'onglet</string> <string name="new_tab">Nouvel onglet</string> @@ -72,15 +73,15 @@ <string name="close">Fermer</string> <string name="domain">Domaine</string> <string name="domain_label">Domaine :</string> - <string name="ip_addresses">Addresse(s) IP:</string> + <string name="ip_addresses">Addresse(s) IP :</string> <string name="issued_to">Delivré à </string> <string name="issued_by">Délivré par</string> - <string name="common_name">Nom courant (CN):</string> - <string name="organization">Organisation (O):</string> - <string name="organizational_unit">Unité Organisationelle (OU):</string> + <string name="common_name">Nom courant (CN) :</string> + <string name="organization">Organisation (O) :</string> + <string name="organizational_unit">Unité Organisationelle (OU) :</string> <string name="valid_dates">Dates de validités</string> - <string name="start_date">Début:</string> - <string name="end_date">Fin:</string> + <string name="start_date">Début :</string> + <string name="end_date">Fin :</string> <!-- SSL Certificate Error. --> <string name="ssl_certificate_error">Erreur de certificat SSL</string> @@ -190,8 +191,7 @@ <string name="file_is_mht">Le fichier est une archive web MHT.</string> <string name="mht_checkbox_explanation">Parfois, les archives web MHT (MIME Encapsulated HTML) doivent être spécifiées manuellement pour être ouvertes correctement.</string> - <!-- Save Dialog. Android removes double spaces, but extra spaces can be manually specified with the Unicode `\u0020` formatting. - The `%*$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> + <!-- Save Dialog. The `%*$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> <string name="save_url">Enregistrer l\'URL</string> <string name="save_archive">Enregistrer l\'archive</string> <string name="save_text">Sauvegarder le texte</string> @@ -202,8 +202,8 @@ <string name="unknown_size">taille inconnue</string> <string name="invalid_url">URL invalide</string> <string name="saving_file">Enregistrement du fichier :</string> - <string name="processing_image">Traitement de l\'image: \u0020 %1$s</string> - <string name="error_saving_file">Erreur lors de l\'enregistrement de %1$s: \u0020 %2$s</string> + <string name="processing_image">Traitement de l\'image : %1$s</string> + <string name="error_saving_file">Erreur lors de l\'enregistrement de %1$s : %2$s</string> <string name="unknown_error">Erreur inconnue</string> <!-- View Source. --> @@ -350,8 +350,7 @@ <string name="saved_ip_addresses">Adresse(s) IP sauvegardée(s)</string> <string name="current_ip_addresses">Adresse(s) IP courante(s)</string> - <!-- Import/Export. Android removes double spaces, but extra spaces can be manually specified with the Unicode `\u0020` formatting. - The `%1$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> + <!-- Import/Export. The `%1$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> <string name="encryption">Chiffrement</string> <string-array name="encryption_type"> <item>Aucun</item> @@ -369,14 +368,13 @@ <string name="export_failed">L\'export a échoué : %1$s</string> <string name="import_failed">L\'import a échoué : %1$s</string> - <!-- Logcat. Android removes double spaces, but extra spaces can be manually specified with the Unicode `\u0020` formatting. - The `%1$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> + <!-- Logcat. The `%1$s` code inserts variables into the displayed text and should be preserved in translation. <https://developer.android.com/reference/kotlin/java/util/Formatter> --> <string name="copy_string">Copie</string> <string name="clear">Vider</string> <string name="logcat_copied">Journal système copié.</string> <string name="privacy_browser_logcat_txt">Privacy Browser %1$s Logcat.txt</string> <string name="saved">%1$s sauvegardé.</string> - <string name="error_saving_logcat">Erreur de sauvegarde du logcat: \u0020 %1$s</string> + <string name="error_saving_logcat">Erreur de sauvegarde du logcat : %1$s</string> <!-- Guide. --> <string name="overview">Présentation</string> -- 2.47.2