Add an `Undo` callback to the `Snackbars` for deleting cookies, DOM storage, and...
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 0c80f526d32c53e9aeefc51249479bdbd408a2cd..f21cae48e51812b8f606a520d45bd2f0049ccb2b 100644 (file)
@@ -205,7 +205,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     private boolean adBlockerEnabled;
 
     // `privacyBrowserRuntime` is used in `onCreate()` and `applyAppSettings()`.
-    Runtime privacyBrowserRuntime;
+    private Runtime privacyBrowserRuntime;
 
     // `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
     private boolean incognitoModeEnabled;
@@ -237,6 +237,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
     // `onTheFlyDisplayImagesSet` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`.
     private boolean onTheFlyDisplayImagesSet;
 
+    // `loadingNewIntentBoolean` is used in `onNewIntent()` and `onRestart()`.
+    private boolean loadingNewIntentBoolean;
+
     // `waitingForOrbotData` is used in `onCreate()` and `applyAppSettings()`.
     private String waitingForOrbotHTMLString;
 
@@ -906,6 +909,32 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         }
     }
 
+    @Override
+    protected void onNewIntent(Intent intent) {
+        // Set `loadingNewIntentBoolean`.
+        loadingNewIntentBoolean = true;
+
+        // Sets the new intent as the activity intent, so that any future `getIntent()`s pick up this one instead of creating a new activity.
+        setIntent(intent);
+
+        if (intent.getData() != null) {
+            // Get the intent data and convert it to a string.
+            final Uri intentUriData = intent.getData();
+            formattedUrlString = intentUriData.toString();
+        }
+
+        // Close the navigation drawer if it is open.
+        if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
+            drawerLayout.closeDrawer(GravityCompat.START);
+        }
+
+        // Load the website.
+        loadUrl(formattedUrlString);
+
+        // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
+        mainWebView.requestFocus();
+    }
+
     @Override
     public void onRestart() {
         super.onRestart();
@@ -919,8 +948,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         // Set the display webpage images mode.
         setDisplayWebpageImages();
 
-        // Reload the webpage to remove images if `setDisplayWebpageImages` has turned them off.
-        mainWebView.reload();
+        // Only reload `mainWebView` if not loading a new intent and not waiting for Orbot.
+        if (!loadingNewIntentBoolean && !waitingForOrbot) {
+            // Reload the webpage to remove images if `setDisplayWebpageImages` has turned them off.
+            mainWebView.reload();
+        } else if (loadingNewIntentBoolean) {  // Reset `loadingNewIntentBoolean` if this run comes from a new intent.
+            loadingNewIntentBoolean = false;
+        }
     }
 
     // `onResume()` runs after `onStart()`, which runs after `onCreate()` and `onRestart()`.
@@ -956,29 +990,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
         super.onPause();
     }
 
-    @Override
-    protected void onNewIntent(Intent intent) {
-        // Sets the new intent as the activity intent, so that any future `getIntent()`s pick up this one instead of creating a new activity.
-        setIntent(intent);
-
-        if (intent.getData() != null) {
-            // Get the intent data and convert it to a string.
-            final Uri intentUriData = intent.getData();
-            formattedUrlString = intentUriData.toString();
-        }
-
-        // Close the navigation drawer if it is open.
-        if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
-            drawerLayout.closeDrawer(GravityCompat.START);
-        }
-
-        // Load the website.
-        loadUrl(formattedUrlString);
-
-        // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
-        mainWebView.requestFocus();
-    }
-
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate the menu; this adds items to the action bar if it is present.
@@ -1247,24 +1258,91 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
                 return true;
 
             case R.id.clear_cookies:
-                if (Build.VERSION.SDK_INT < 21) {
-                    cookieManager.removeAllCookie();
-                } else {
-                    cookieManager.removeAllCookies(null);
-                }
-                Snackbar.make(findViewById(R.id.main_webview), R.string.cookies_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.cookies_deleted, Snackbar.LENGTH_LONG)
+                        .setAction(R.string.undo, new View.OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                // Do nothing because everything will be handled by `onDismissed()` below.
+                            }
+                        })
+                        .addCallback(new Snackbar.Callback() {
+                            @Override
+                            public void onDismissed(Snackbar snackbar, int event) {
+                                switch (event) {
+                                    // The user pushed the `Undo` button.
+                                    case Snackbar.Callback.DISMISS_EVENT_ACTION:
+                                        // Do nothing.
+                                        break;
+
+                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    default:
+                                        // `cookieManager.removeAllCookie()` varies by SDK.
+                                        if (Build.VERSION.SDK_INT < 21) {
+                                            cookieManager.removeAllCookie();
+                                        } else {
+                                            // `null` indicates no callback.
+                                            cookieManager.removeAllCookies(null);
+                                        }
+                                }
+                            }
+                        })
+                        .show();
                 return true;
 
             case R.id.clear_dom_storage:
-                WebStorage webStorage = WebStorage.getInstance();
-                webStorage.deleteAllData();
-                Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_deleted, Snackbar.LENGTH_LONG)
+                        .setAction(R.string.undo, new View.OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                // Do nothing because everything will be handled by `onDismissed()` below.
+                            }
+                        })
+                        .addCallback(new Snackbar.Callback() {
+                            @Override
+                            public void onDismissed(Snackbar snackbar, int event) {
+                                switch (event) {
+                                    // The user pushed the `Undo` button.
+                                    case Snackbar.Callback.DISMISS_EVENT_ACTION:
+                                        // Do nothing.
+                                        break;
+
+                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    default:
+                                        // Delete the DOM Storage.
+                                        WebStorage webStorage = WebStorage.getInstance();
+                                        webStorage.deleteAllData();
+                                }
+                            }
+                        })
+                        .show();
                 return true;
 
             case R.id.clear_form_data:
-                WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
-                mainWebViewDatabase.clearFormData();
-                Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_deleted, Snackbar.LENGTH_SHORT).show();
+                Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_deleted, Snackbar.LENGTH_LONG)
+                        .setAction(R.string.undo, new View.OnClickListener() {
+                            @Override
+                            public void onClick(View v) {
+                                // Do nothing because everything will be handled by `onDismissed()` below.
+                            }
+                        })
+                        .addCallback(new Snackbar.Callback() {
+                            @Override
+                            public void onDismissed(Snackbar snackbar, int event) {
+                                switch (event) {
+                                    // The user pushed the `Undo` button.
+                                    case Snackbar.Callback.DISMISS_EVENT_ACTION:
+                                        // Do nothing.
+                                        break;
+
+                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    default:
+                                        // Delete the form data.
+                                        WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(getApplicationContext());
+                                        mainWebViewDatabase.clearFormData();
+                                }
+                            }
+                        })
+                        .show();
                 return true;
 
             case R.id.font_size_twenty_five_percent:
@@ -1774,6 +1852,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(imageUrl));
 
             // Pass cookies to download manager if cookies are enabled.  This is required to download images from websites that require a login.
+            // Code contributed 2017 Hendrik Knackstedt.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
             if (firstPartyCookiesEnabled) {
                 // Get the cookies for `imageUrl`.
                 String cookies = cookieManager.getCookie(imageUrl);
@@ -1821,6 +1900,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation
             DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(downloadUrl));
 
             // Pass cookies to download manager if cookies are enabled.  This is required to download files from websites that require a login.
+            // Code contributed 2017 Hendrik Knackstedt.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
             if (firstPartyCookiesEnabled) {
                 // Get the cookies for `downloadUrl`.
                 String cookies = cookieManager.getCookie(downloadUrl);