]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.kt
Migrate the remaining classes to Kotlin. https://redmine.stoutner.com/issues/989
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / views / NestedScrollWebView.kt
index cd00f067cd6a68273afc113eeac2234d9033042d..aa2ea0984035fe561888abcce7f505b635d36f16 100644 (file)
@@ -1,24 +1,25 @@
 /*
- * Copyright © 2019-2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2019-2023 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
  *
- * Privacy Browser is free software: you can redistribute it and/or modify
+ * Privacy Browser Android is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
- * Privacy Browser is distributed in the hope that it will be useful,
+ * Privacy Browser Android is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.stoutner.privacybrowser.views
 
+import android.animation.ObjectAnimator
 import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.Bitmap
@@ -26,25 +27,34 @@ import android.graphics.drawable.BitmapDrawable
 import android.os.Bundle
 import android.util.AttributeSet
 import android.view.MotionEvent
-import android.webkit.WebView
-import android.webkit.SslErrorHandler
 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
 
 import com.stoutner.privacybrowser.R
+import com.stoutner.privacybrowser.activities.MainWebViewActivity
 
 import java.util.Collections
 import java.util.Date
 
 import kotlin.collections.ArrayList
 
-import kotlin.jvm.JvmOverloads
-
-// Define the saved state constants.
+// Define the public constants.
+const val BLOCKED_REQUESTS = 0
+const val EASYLIST = 1
+const val EASYPRIVACY = 2
+const val FANBOYS_ANNOYANCE_LIST = 3
+const val FANBOYS_SOCIAL_BLOCKING_LIST = 4
+const val ULTRALIST = 5
+const val ULTRAPRIVACY = 6
+const val THIRD_PARTY_REQUESTS = 7
+
+// Define the private class constants.
 private const val DOMAIN_SETTINGS_APPLIED = "domain_settings_applied"
 private const val DOMAIN_SETTINGS_DATABASE_ID = "domain_settings_database_id"
 private const val CURRENT_DOMAIN_NAME = "current_domain_name"
@@ -79,18 +89,6 @@ private const val FONT_SIZE = "font_size"
 class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defaultStyle: Int = android.R.attr.webViewStyle) : WebView(context, attributeSet, defaultStyle),
     NestedScrollingChild2 {
 
-    companion object {
-        // Define the public companion object blocklists constants.
-        const val BLOCKED_REQUESTS = 0
-        const val EASYLIST = 1
-        const val EASYPRIVACY = 2
-        const val FANBOYS_ANNOYANCE_LIST = 3
-        const val FANBOYS_SOCIAL_BLOCKING_LIST = 4
-        const val ULTRALIST = 5
-        const val ULTRAPRIVACY = 6
-        const val THIRD_PARTY_REQUESTS = 7
-    }
-
     // Define the public variables.
     var acceptCookies = false
     var blockAllThirdPartyRequests = false
@@ -113,10 +111,10 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
     var waitingForProxyUrlString = ""
     var webViewFragmentId: Long = 0
 
-
     // 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 = ""
@@ -145,22 +143,27 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
         initializeFavoriteIcon()
     }
 
-
     // 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.
@@ -168,11 +171,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() {
@@ -207,22 +214,15 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
         hasPinnedSslCertificate = true
     }
 
-    fun getPinnedSslCertificate(): ArrayList<Any> {
-        // Initialize an array list.
-        val arrayList = ArrayList<Any>()
-
+    fun getPinnedSslCertificate(): Pair<Array<String>, Array<Date>> {
         // Create the SSL certificate string array.
         val sslCertificateStringArray = arrayOf(pinnedSslIssuedToCName, pinnedSslIssuedToOName, pinnedSslIssuedToUName, pinnedSslIssuedByCName, pinnedSslIssuedByOName, pinnedSslIssuedByUName)
 
         // Create the SSL certificate date array.
         val sslCertificateDateArray = arrayOf(pinnedSslStartDate, pinnedSslEndDate)
 
-        // Add the arrays to the array list.
-        arrayList.add(sslCertificateStringArray)
-        arrayList.add(sslCertificateDateArray)
-
-        // Return the pinned SSL certificate array list.
-        return arrayList
+        // Return the pinned SSL certificate pair.
+        return Pair(sslCertificateStringArray, sslCertificateDateArray)
     }
 
     fun clearPinnedSslCertificate() {
@@ -312,6 +312,19 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
         return computeVerticalScrollRange()
     }
 
+    override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
+        // Run the default commands.
+        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)
+
+        // Display the bottom app bar if it has been hidden and the WebView was over-scrolled at the top of the screen.
+        if ((MainWebViewActivity.appBarLayout.translationY != 0f) && (scrollY == 0) && clampedY) {
+            // Animate the bottom app bar onto the screen.
+            val objectAnimator = ObjectAnimator.ofFloat(MainWebViewActivity.appBarLayout, "translationY", 0f)
+
+            // Make it so.
+            objectAnimator.start()
+        }
+    }
 
     // Handle touches.
     @SuppressLint("ClickableViewAccessibility")
@@ -376,7 +389,7 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
     }
 
 
-    // Save and restore state.
+    // Save the state.
     fun saveNestedScrollWebViewState(): Bundle {
         // Create a saved state bundle.
         val savedState = Bundle()
@@ -416,6 +429,7 @@ class NestedScrollWebView @JvmOverloads constructor(context: Context, attributeS
         return savedState
     }
 
+    // Restore the state.
     fun restoreNestedScrollWebViewState(savedState: Bundle) {
         // Restore the class variables.
         domainSettingsApplied = savedState.getBoolean(DOMAIN_SETTINGS_APPLIED)
@@ -533,4 +547,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
+}