]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/commitdiff
Open new tabs adjacent to the current tab. https://redmine.stoutner.com/issues/1100
authorSoren Stoutner <soren@stoutner.com>
Mon, 13 Nov 2023 18:39:48 +0000 (11:39 -0700)
committerSoren Stoutner <soren@stoutner.com>
Mon, 13 Nov 2023 18:39:48 +0000 (11:39 -0700)
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.kt
app/src/main/java/com/stoutner/privacybrowser/adapters/WebViewStateAdapter.kt
app/src/main/java/com/stoutner/privacybrowser/fragments/WebViewTabFragment.kt

index dc63adf65cb190d9b0adfa2edd14e6b75758dfb0..13ae3b784456fac7046c78968f27f677ac603287 100644 (file)
@@ -778,7 +778,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                     loadingNewIntent = true
 
                     // Add a new tab.
-                    addNewTab(url!!, true)
+                    addNewTab(url!!, adjacent = false, moveToTab = true)
                 } else {  // Load the URL in the current tab.
                     // Make it so.
                     loadUrl(currentWebView!!, url!!)
@@ -2006,10 +2006,10 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Open a new tab according to the current URL.
                 if (currentWebView!!.currentUrl.startsWith("view-source:")) {  // The source is currently viewed.
                     // Open the rendered website in a new tab.
-                    addNewTab(currentWebView!!.currentUrl.substring(12, currentWebView!!.currentUrl.length), true)
+                    addNewTab(currentWebView!!.currentUrl.substring(12, currentWebView!!.currentUrl.length), true, moveToTab = true)
                 } else {  // The rendered website is currently viewed.
                     // Open the source in a new tab.
-                    addNewTab("view-source:${currentWebView!!.currentUrl}", true)
+                    addNewTab("view-source:${currentWebView!!.currentUrl}", adjacent = true, moveToTab = true)
                 }
 
                 // Consume the event.
@@ -2579,7 +2579,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open in new tab entry.
                 contextMenu.add(R.string.open_in_new_tab).setOnMenuItemClickListener {
                     // Load the link URL in a new tab and move to it.
-                    addNewTab(linkUrl, true)
+                    addNewTab(linkUrl, adjacent = true, moveToTab = true)
 
                     // Consume the event.
                     true
@@ -2588,7 +2588,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open in background entry.
                 contextMenu.add(R.string.open_in_background).setOnMenuItemClickListener {
                     // Load the link URL in a new tab but do not move to it.
-                    addNewTab(linkUrl, false)
+                    addNewTab(linkUrl, adjacent = true, moveToTab = false)
 
                     // Consume the event.
                     true
@@ -2675,7 +2675,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open in new tab entry.
                 contextMenu.add(R.string.open_image_in_new_tab).setOnMenuItemClickListener {
                     // Load the image in a new tab.
-                    addNewTab(imageUrl, true)
+                    addNewTab(imageUrl, adjacent = true, moveToTab = true)
 
                     // Consume the event.
                     true
@@ -2781,7 +2781,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open in new tab entry.
                 contextMenu.add(R.string.open_in_new_tab).setOnMenuItemClickListener {
                     // Load the link URL in a new tab and move to it.
-                    addNewTab(linkUrl, true)
+                    addNewTab(linkUrl, adjacent = true, moveToTab = true)
 
                     // Consume the event.
                     true
@@ -2790,7 +2790,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open in background entry.
                 contextMenu.add(R.string.open_in_background).setOnMenuItemClickListener {
                     // Lod the link URL in a new tab but do not move to it.
-                    addNewTab(linkUrl, false)
+                    addNewTab(linkUrl, adjacent = true, moveToTab = false)
 
                     // Consume the event.
                     true
@@ -2799,7 +2799,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Add an open image in new tab entry.
                 contextMenu.add(R.string.open_image_in_new_tab).setOnMenuItemClickListener {
                     // Load the image in a new tab and move to it.
-                    addNewTab(imageUrl, true)
+                    addNewTab(imageUrl, adjacent = true, moveToTab = true)
 
                     // Consume the event.
                     true
@@ -2965,30 +2965,38 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
     // The view parameter cannot be removed because it is called from the layout onClick.
     fun addTab(@Suppress("UNUSED_PARAMETER")view: View?) {
         // Add a new tab with a blank URL.
-        addNewTab("", true)
+        addNewTab(urlString = "", adjacent = true, moveToTab = true)
     }
 
-    private fun addNewTab(urlString: String, moveToTab: Boolean) {
+    private fun addNewTab(urlString: String, adjacent: Boolean, moveToTab: Boolean) {
         // Clear the focus from the URL edit text, so that it will be populated with the information from the new tab.
         urlEditText.clearFocus()
 
-        // Get the new page number.  The page numbers are 0 indexed, so the new page number will match the current count.
-        val newTabNumber = tabLayout.tabCount
+        // Get the new tab position.
+        val newTabPosition = if (adjacent)  // The new tab position is immediately to the right of the current tab position.
+            tabLayout.selectedTabPosition + 1
+        else  // The new tab position is at the end.  The tab positions are 0 indexed, so the new page number will match the current count.
+            tabLayout.tabCount
 
-        // Add a new tab.
-        tabLayout.addTab(tabLayout.newTab())
+        // Add the new WebView page.
+        webViewStateAdapter!!.addPage(newTabPosition, urlString)
 
-        // Get the new tab.
-        val newTab = tabLayout.getTabAt(newTabNumber)!!
+        // Create a new tab.
+        val newTab = tabLayout.newTab()
 
         // Set a custom view on the new tab.
         newTab.setCustomView(R.layout.tab_custom_view)
 
-        // Scroll to the new tab position.
-        tabLayout.post { tabLayout.setScrollPosition(newTabNumber, 0F, false, false) }
+        // Add the new tab.
+        tabLayout.addTab(newTab, newTabPosition, moveToTab)
 
-        // Add the new WebView page.
-        webViewStateAdapter!!.addPage(newTabNumber, newTab, urlString, moveToTab)
+        // Select the new tab if it is the first one.  For some odd reason, Android doesn't select the first tab if it is the only one, which causes problems with the new tab position logic above.
+        if (newTabPosition == 0)
+            tabLayout.selectTab(newTab)
+
+        // Scroll to the new tab position if moving to the new tab.
+        if (moveToTab)
+            tabLayout.post { tabLayout.setScrollPosition(newTabPosition, 0F, false, false) }
 
         // Show the app bar if it is at the bottom of the screen and the new tab is taking focus.
         if (bottomAppBar && moveToTab && appBarLayout.translationY != 0f) {
@@ -4193,7 +4201,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
         // Check to see if the activity has been restarted with a saved state.
         if ((savedStateArrayList == null) || (savedStateArrayList!!.size == 0)) {  // The activity has not been restarted or it was restarted on start to change the theme.
             // Add the first tab.
-            addNewTab("", false)
+            addNewTab(urlString = "", adjacent = false, moveToTab = false)
         } else {  // The activity has been restarted with a saved state.
             // Restore each tab.
             for (i in savedStateArrayList!!.indices) {
@@ -4252,7 +4260,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                     loadingNewIntent = true
 
                     // Add a new tab.
-                    addNewTab(urlString, true)
+                    addNewTab(urlString, adjacent = false, moveToTab = true)
                 } else {  // Load the URL in the current tab.
                     // Make it so.
                     loadUrl(currentWebView!!, urlString)
@@ -4573,7 +4581,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 // Open each bookmark
                 for (i in 0 until bookmarksCursor.count) {
                     // Load the bookmark in a new tab, moving to the tab for the first bookmark if the drawer is not pinned.
-                    addNewTab(bookmarksCursor.getString(bookmarksCursor.getColumnIndexOrThrow(BOOKMARK_URL)), !bookmarksDrawerPinned && (i == 0))
+                    addNewTab(bookmarksCursor.getString(bookmarksCursor.getColumnIndexOrThrow(BOOKMARK_URL)), adjacent = false, moveToTab = !bookmarksDrawerPinned && (i == 0))
 
                     // Move to the next bookmark.
                     bookmarksCursor.moveToNext()
@@ -4589,7 +4597,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
                 bookmarkCursor.moveToFirst()
 
                 // Load the bookmark in a new tab and move to the tab if the drawer is not pinned.
-                addNewTab(bookmarkCursor.getString(bookmarkCursor.getColumnIndexOrThrow(BOOKMARK_URL)), !bookmarksDrawerPinned)
+                addNewTab(bookmarkCursor.getString(bookmarkCursor.getColumnIndexOrThrow(BOOKMARK_URL)), adjacent = true, moveToTab = !bookmarksDrawerPinned)
 
                 // Close the cursor.
                 bookmarkCursor.close()
@@ -4690,7 +4698,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
     }
 
     @SuppressLint("ClickableViewAccessibility")
-    override fun initializeWebView(nestedScrollWebView: NestedScrollWebView, pageNumber: Int, progressBar: ProgressBar, urlString: String, restoringState: Boolean) {
+    override fun initializeWebView(nestedScrollWebView: NestedScrollWebView, pagePosition: Int, progressBar: ProgressBar, urlString: String, restoringState: Boolean) {
         // Get the WebView theme.
         val webViewTheme = sharedPreferences.getString(getString(R.string.webview_theme_key), getString(R.string.webview_theme_default_value))
 
@@ -5838,7 +5846,7 @@ class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBook
         if (restoringState) {  // The state is being restored.
             // Resume the nested scroll WebView JavaScript timers.
             nestedScrollWebView.resumeTimers()
-        } else if (pageNumber == 0) {  // The first page is being loaded.
+        } else if (pagePosition == 0) {  // The first page is being loaded.
             // Set this nested scroll WebView as the current WebView.
             currentWebView = nestedScrollWebView
 
index e67a99a3abeb717fdf406196b4646b89bc2118eb..7a7913a5de77dc7288f192cc380976c7df31594c 100644 (file)
@@ -28,8 +28,6 @@ import androidx.recyclerview.widget.RecyclerView.NO_ID
 import androidx.viewpager2.adapter.FragmentStateAdapter
 import androidx.viewpager2.widget.ViewPager2
 
-import com.google.android.material.tabs.TabLayout
-
 import com.stoutner.privacybrowser.R
 import com.stoutner.privacybrowser.fragments.WebViewTabFragment
 import com.stoutner.privacybrowser.views.NestedScrollWebView
@@ -84,18 +82,12 @@ class WebViewStateAdapter(fragmentActivity: FragmentActivity) : FragmentStateAda
             NO_ID
     }
 
-    fun addPage(pageNumber: Int, newTab: TabLayout.Tab, url: String, moveToNewPage: Boolean) {
+    fun addPage(pagePosition: Int, url: String) {
         // Add a new page.
-        webViewFragmentsList.add(WebViewTabFragment.createPage(pageNumber, url))
+        webViewFragmentsList.add(pagePosition, WebViewTabFragment.createPage(pagePosition, url))
 
         // Update the view pager.
-        notifyItemInserted(pageNumber)
-
-        // Move to the new page if indicated.
-        if (moveToNewPage) {
-            // Select the newTab.
-            newTab.select()
-        }
+        notifyItemInserted(pagePosition)
     }
 
     fun deletePage(pageNumber: Int, webViewPager2: ViewPager2): Boolean {
index 4811221a171a0cce782527d947db2e20ecdc38c7..34568cb50ee073a4716b5967671bba2da2626517 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2019-2020,2022-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2019-2020,2022-2023 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
  *
@@ -35,11 +35,11 @@ import com.stoutner.privacybrowser.views.NestedScrollWebView
 import java.util.Calendar
 
 // Define the class constants.
-private const val CREATE_NEW_PAGE = "create_new_page"
-private const val PAGE_NUMBER = "page_number"
-private const val URL = "url"
-private const val SAVED_STATE = "saved_state"
-private const val SAVED_NESTED_SCROLL_WEBVIEW_STATE = "saved_nested_scroll_webview_state"
+private const val CREATE_NEW_PAGE = "A"
+private const val PAGE_POSITION = "B"
+private const val URL = "C"
+private const val SAVED_STATE = "D"
+private const val SAVED_NESTED_SCROLL_WEBVIEW_STATE = "E"
 
 class WebViewTabFragment : Fragment() {
     // Define the public variables.
@@ -48,7 +48,7 @@ class WebViewTabFragment : Fragment() {
     // The public interface is used to send information back to the parent activity.
     interface NewTabListener {
         @SuppressLint("ClickableViewAccessibility")
-        fun initializeWebView(nestedScrollWebView: NestedScrollWebView, pageNumber: Int, progressBar: ProgressBar, urlString: String, restoringState: Boolean)
+        fun initializeWebView(nestedScrollWebView: NestedScrollWebView, pagePosition: Int, progressBar: ProgressBar, urlString: String, restoringState: Boolean)
     }
 
     // Declare the class variables.
@@ -64,7 +64,7 @@ class WebViewTabFragment : Fragment() {
 
             // Store the argument in the bundle.
             argumentsBundle.putBoolean(CREATE_NEW_PAGE, true)
-            argumentsBundle.putInt(PAGE_NUMBER, pageNumber)
+            argumentsBundle.putInt(PAGE_POSITION, pageNumber)
             argumentsBundle.putString(URL, url)
 
             // Create a new instance of the WebView tab fragment.
@@ -110,7 +110,7 @@ class WebViewTabFragment : Fragment() {
             // Check to see if a new page is being created.
             if (requireArguments().getBoolean(CREATE_NEW_PAGE)) {  // A new page is being created.
                 // Get the variables from the arguments
-                val pageNumber = requireArguments().getInt(PAGE_NUMBER)
+                val pagePosition = requireArguments().getInt(PAGE_POSITION)
                 val url = requireArguments().getString(URL)!!
 
                 // Inflate the tab's WebView.  Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container.
@@ -125,7 +125,7 @@ class WebViewTabFragment : Fragment() {
                 nestedScrollWebView.webViewFragmentId = fragmentId
 
                 // Request the main activity initialize the WebView.
-                newTabListener.initializeWebView(nestedScrollWebView, pageNumber, progressBar, url, false)
+                newTabListener.initializeWebView(nestedScrollWebView, pagePosition, progressBar, url, false)
 
                 // Return the new page view.
                 newPageView