Fix problems with swipe to refresh. https://redmine.stoutner.com/issues/514
authorSoren Stoutner <soren@stoutner.com>
Wed, 3 Jun 2020 19:19:59 +0000 (12:19 -0700)
committerSoren Stoutner <soren@stoutner.com>
Wed, 3 Jun 2020 19:19:59 +0000 (12:19 -0700)
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/res/values-de/strings.xml
app/src/main/res/values-es/strings.xml
app/src/main/res/values-fr/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values/strings.xml

index becbd5ac8ab5fd55ed65b6305196082fd87518f4..89a73f25608c99c1254ccc32cff939477fe40e8e 100644 (file)
@@ -4050,23 +4050,29 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         // Store the swipe to refresh status in the nested scroll WebView.
                         nestedScrollWebView.setSwipeToRefresh(defaultSwipeToRefresh);
 
-                        // Apply swipe to refresh according to the default.  This can be removed once the minimum API >= 23 because it is continuously set by an on scroll change listener.
-                        swipeRefreshLayout.setEnabled(defaultSwipeToRefresh);
+                        // Update the swipe refresh layout.
+                        if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
+                            // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
+                            swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                        } else {  // Swipe to refresh is disabled.
+                            // Disable the swipe refresh layout.
+                            swipeRefreshLayout.setEnabled(false);
+                        }
                         break;
 
                     case DomainsDatabaseHelper.ENABLED:
                         // Store the swipe to refresh status in the nested scroll WebView.
                         nestedScrollWebView.setSwipeToRefresh(true);
 
-                        // Enable swipe to refresh.  This can be removed once the minimum API >= 23 because it is continuously set by an on scroll change listener.
-                        swipeRefreshLayout.setEnabled(true);
+                        // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
+                        swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
                         break;
 
                     case DomainsDatabaseHelper.DISABLED:
                         // Store the swipe to refresh status in the nested scroll WebView.
                         nestedScrollWebView.setSwipeToRefresh(false);
 
-                        // Disable swipe to refresh.  This can be removed once the minimum API >= 23 because it is continuously set by an on scroll change listener.
+                        // Disable swipe to refresh.
                         swipeRefreshLayout.setEnabled(false);
                 }
 
@@ -4154,8 +4160,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Store the swipe to refresh status in the nested scroll WebView.
                 nestedScrollWebView.setSwipeToRefresh(defaultSwipeToRefresh);
 
-                // Apply swipe to refresh according to the default.
-                swipeRefreshLayout.setEnabled(defaultSwipeToRefresh);
+                // Update the swipe refresh layout.
+                if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
+                    // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
+                    swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                } else {  // Swipe to refresh is disabled.
+                    // Disable the swipe refresh layout.
+                    swipeRefreshLayout.setEnabled(false);
+                }
 
                 // Reset the pinned variables.
                 nestedScrollWebView.setDomainSettingsDatabaseId(-1);
@@ -5176,26 +5188,55 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         });
 
         // Update the status of swipe to refresh based on the scroll position of the nested scroll WebView.  Also reinforce full screen browsing mode.
-        // Once the minimum API >= 23 this can be replaced with `nestedScrollWebView.setOnScrollChangeListener()`.
-        nestedScrollWebView.getViewTreeObserver().addOnScrollChangedListener(() -> {
-            if (nestedScrollWebView.getSwipeToRefresh()) {
-                // Only enable swipe to refresh if the WebView is scrolled to the top.
-                swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0);
-            }
+        // On API < 23, `getViewTreeObserver().addOnScrollChangedListener()` must be used, but it is a little bit buggy and appears to get garbage collected from time to time.
+        if (Build.VERSION.SDK_INT >= 23) {
+            nestedScrollWebView.setOnScrollChangeListener((view, i, i1, i2, i3) -> {
+                if (nestedScrollWebView.getSwipeToRefresh()) {
+                    // Only enable swipe to refresh if the WebView is scrolled to the top.
+                    swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0);
+                } else {
+                    // Disable swipe to refresh.
+                    swipeRefreshLayout.setEnabled(false);
+                }
 
-            // Reinforce the system UI visibility flags if in full screen browsing mode.
-            // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard.
-            if (inFullScreenBrowsingMode) {
-                /* Hide the system bars.
-                 * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
-                 * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
-                 * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
-                 * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
-                 */
-                rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
-            }
-        });
+                // Reinforce the system UI visibility flags if in full screen browsing mode.
+                // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard.
+                if (inFullScreenBrowsingMode) {
+                    /* Hide the system bars.
+                     * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
+                     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
+                     * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
+                     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
+                     */
+                    rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                }
+            });
+        } else {
+            nestedScrollWebView.getViewTreeObserver().addOnScrollChangedListener(() -> {
+                if (nestedScrollWebView.getSwipeToRefresh()) {
+                    // Only enable swipe to refresh if the WebView is scrolled to the top.
+                    swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0);
+                } else {
+                    // Disable swipe to refresh.
+                    swipeRefreshLayout.setEnabled(false);
+                }
+
+
+                // Reinforce the system UI visibility flags if in full screen browsing mode.
+                // This hides the status and navigation bars, which are displayed if other elements are shown, like dialog boxes, the options menu, or the keyboard.
+                if (inFullScreenBrowsingMode) {
+                    /* Hide the system bars.
+                     * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
+                     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
+                     * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
+                     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
+                     */
+                    rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                }
+            });
+        }
 
         // Set the web chrome client.
         nestedScrollWebView.setWebChromeClient(new WebChromeClient() {
index 4c5b84a4b848cd61a9e5bc9936ebbfb1afce7d49..5e282ead13e6bd695215064a848985d5f8aae971 100644 (file)
         </string-array>
         <string name="custom_user_agent">Eigener User Agent</string>
         <string name="incognito_mode">Inkognito-Modus</string>
-        <string name="incognito_mode_summary">Löscht den Verlauf und den Cache nach jedem fertigen Laden einer Webseite. Zurück und vorwärts funktioniert im Inkognito-Modus nicht.</string>
+        <string name="incognito_mode_summary">Löscht den Verlauf und den Cache nach jedem fertigen Laden einer Webseite.
+            Im Incognito-Modus schliesst \'Zurück\'-Button den aktive Tab (oder die App, wenn nur ein Tab geöffnet wurde).</string>
         <string name="do_not_track">Nicht verfolgen (Do not track)</string>
         <string name="do_not_track_summary">Einen "Do Not Track-Header" senden, der freundlich anfragt, dass Webserver diesen Browser nicht nachverfolgen sollen.</string>
         <string name="allow_screenshots">Screenshots zulassen</string>
index 2928a6ed8c72f66c99bc61639179d7db8a98c33d..1152e50ca201ac970eb8f7174c0d8aa21126e449 100644 (file)
         </string-array>
         <string name="custom_user_agent">Agente de usuario personalizado</string>
         <string name="incognito_mode">Modo incógnito</string>
-        <string name="incognito_mode_summary">Borrar el historial y el caché después de que cada página web termine de cargar. Adelante y atrás no funcionan en el Modo incógnito.</string>
+        <string name="incognito_mode_summary">Borrar el historial y el caché después de que cada página web termine de cargar.
+            En el modo Incógnito, Atrás cierra la pestaña (o la app si hay solo una pestaña).</string>
         <string name="do_not_track">No rastrear</string>
         <string name="do_not_track_summary">Enviar la cabecera de no rastrear (DNT) que educadamente sugiere que los servidores web no rastreen este navegador.</string>
         <string name="allow_screenshots">Permitir capturas de pantalla</string>
index afd9e9dc97b9cc46f78b932235bdbf94d6e52347..a2923cee6d7b583a915bbbf57983287f6ec54bd8 100644 (file)
         </string-array>
         <string name="custom_user_agent">User agent personnalisé</string>
         <string name="incognito_mode">Mode Incognito</string>
-        <string name="incognito_mode_summary">Vider l\'historique et le cache après le chargement de chaque page. Précédent et Suivant ne fonctionnent pas en mode Incognito.</string>
+        <string name="incognito_mode_summary">Vider l\'historique et le cache après le chargement de chaque page. In Incognito Mode, back closes the tab (or the app if there is only one tab).</string>
         <string name="do_not_track">Ne pas me pister</string>
         <string name="do_not_track_summary">Envoyer aux sites web un signal «Ne pas me pister» indiquant poliement que vous ne souhaitez pas être pisté</string>
         <string name="allow_screenshots">Autoriser captures d\'écrans</string>
index 051a38b18e32c8cc971b6309a5e4b20230b3bebe..874c6972f2ce5b3b53c06d6c6b25220876c1e197 100644 (file)
         </string-array>
         <string name="custom_user_agent">User agent personalizzato</string>
         <string name="incognito_mode">Modalità Incognito</string>
-        <string name="incognito_mode_summary">Cancella la cronologia e la cache al termine del caricamento di ogni pagina. I pulsanti Avanti e Indietro non funzionano in modalità incognito.</string>
+        <string name="incognito_mode_summary">Cancella la cronologia e la cache al termine del caricamento di ogni pagina.
+            In Modalità Incognito, il tasto "Indietro" chiude la scheda (o l\'applicazione se è aperta solo una scheda).</string>
         <string name="do_not_track">Non tracciare</string>
         <string name="do_not_track_summary">Invia un\'intestazione di non tracciamento per chiedere al web server di non tracciare il browser.</string>
         <string name="allow_screenshots">Permetti gli screenshot</string>
index 51fafbd953256ca0874029e18b1e58c6f9ec3af3..4e32aa5cd21d4b230fbca9a1dced4bc78de489a8 100644 (file)
         </string-array>
         <string name="custom_user_agent">Настраиваемый user agent</string>
         <string name="incognito_mode">Режим инкогнито</string>
-        <string name="incognito_mode_summary">Очистка журнала и кэша после завершения загрузки каждой веб-страницы. Кнопки \'Вперед\' и \'Назад\' не работают в этом режиме.</string>
+        <string name="incognito_mode_summary">Очистка журнала и кэша по завершении загрузки каждой веб-страницы.
+            В режиме инкогнито нажатие кнопки Назад приведет к закрытию вкладки (или приложения, если открыта только одна вкладка).</string>
         <string name="do_not_track">Не отслеживать</string>
         <string name="do_not_track_summary">Отправлять заголовок \'Не отслеживать\', предлагающий веб-серверу не отслеживать этот браузер.</string>
         <string name="allow_screenshots">Разрешить скриншоты</string>
index 87c8351c023fa8724b8f88e532951d5af89dd0b7..5f0b590cf9059a18d12a0d8b6cf8842cda5c2528 100644 (file)
         </string-array>
         <string name="custom_user_agent">Özel kullanıcı aracısı</string>
         <string name="incognito_mode">Gizli Mod</string>
-        <string name="incognito_mode_summary">Her web sayfasının yüklenmesi bittikten sonra geçmişi ve önbelleği temizler. İleri ve geri seçenekleri Gizli Mod aktifken çalışmaz.</string>
+        <string name="incognito_mode_summary">Her web sayfasının yüklenmesi bittikten sonra geçmişi ve önbelleği temizler. In Incognito Mode, back closes the tab (or the app if there is only one tab).</string>
         <string name="do_not_track">Takip Etme</string>
         <string name="do_not_track_summary">Web Serverlarına bu tarayıcıyı takip etmemesi için Takip Etme Başlığı gönderir.</string>
         <string name="allow_screenshots">Ekran görüntülerine izin ver</string>
index e6c35629ea80a6a385dabfd4530b1f2ea20f1685..91df074d01aabc4982bce5519cbfe4f7d330b8c1 100644 (file)
         <string name="custom_user_agent">Custom user agent</string>
         <string name="system_default_user_agent" translatable="false">System default user agent</string>  <!-- This item is referenced in code.  It is never displayed on the screen. -->
         <string name="incognito_mode">Incognito Mode</string>
-        <string name="incognito_mode_summary">Clear the history and cache after each webpage finishes loading. Forward and back do not work in Incognito Mode.</string>
+        <string name="incognito_mode_summary">Clear the history and cache after each webpage finishes loading. In Incognito Mode, back closes the tab (or the app if there is only one tab).</string>
         <string name="do_not_track">Do Not Track</string>
         <string name="do_not_track_summary">Send the Do Not Track header, which politely suggests that web servers not track this browser.</string>
         <string name="allow_screenshots">Allow screenshots</string>