Skip to content

Commit 8168a29

Browse files
committed
Merge branch 'hotfix/5.227.1'
2 parents 4cdb239 + e87ba67 commit 8168a29

File tree

5 files changed

+100
-121
lines changed

5 files changed

+100
-121
lines changed

app/src/main/java/com/duckduckgo/app/browser/tabpreview/TabEntityDiffCallback.kt

Lines changed: 0 additions & 109 deletions
This file was deleted.

app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,12 @@ class TabSwitcherActivity : DuckDuckGoActivity(), TabSwitcherListener, Coroutine
404404
tabsAdapter.getTabSwitcherItem(position)?.let { tab ->
405405
when (tab) {
406406
is TabSwitcherItem.Tab -> {
407-
launch { viewModel.onTabDeleted(tab.tabEntity) }
407+
launch {
408+
viewModel.onMarkTabAsDeletable(
409+
tab = tab.tabEntity,
410+
swipeGestureUsed = deletedBySwipe,
411+
)
412+
}
408413
}
409414
}
410415
}

app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import android.view.View
2424
import android.view.ViewGroup
2525
import android.widget.ImageView
2626
import android.widget.TextView
27+
import androidx.annotation.VisibleForTesting
2728
import androidx.lifecycle.LifecycleOwner
2829
import androidx.lifecycle.lifecycleScope
2930
import androidx.recyclerview.widget.DiffUtil
31+
import androidx.recyclerview.widget.RecyclerView
3032
import androidx.recyclerview.widget.RecyclerView.Adapter
3133
import androidx.recyclerview.widget.RecyclerView.ViewHolder
3234
import com.bumptech.glide.Glide
@@ -35,12 +37,12 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
3537
import com.duckduckgo.app.browser.databinding.ItemTabGridBinding
3638
import com.duckduckgo.app.browser.databinding.ItemTabListBinding
3739
import com.duckduckgo.app.browser.favicon.FaviconManager
38-
import com.duckduckgo.app.browser.tabpreview.TabEntityDiffCallback.Companion.DIFF_KEY_PREVIEW
39-
import com.duckduckgo.app.browser.tabpreview.TabEntityDiffCallback.Companion.DIFF_KEY_TITLE
40-
import com.duckduckgo.app.browser.tabpreview.TabEntityDiffCallback.Companion.DIFF_KEY_URL
41-
import com.duckduckgo.app.browser.tabpreview.TabEntityDiffCallback.Companion.DIFF_KEY_VIEWED
4240
import com.duckduckgo.app.browser.tabpreview.WebViewPreviewPersister
4341
import com.duckduckgo.app.browser.tabs.adapter.TabSwitcherItemDiffCallback
42+
import com.duckduckgo.app.browser.tabs.adapter.TabSwitcherItemDiffCallback.Companion.DIFF_KEY_PREVIEW
43+
import com.duckduckgo.app.browser.tabs.adapter.TabSwitcherItemDiffCallback.Companion.DIFF_KEY_TITLE
44+
import com.duckduckgo.app.browser.tabs.adapter.TabSwitcherItemDiffCallback.Companion.DIFF_KEY_URL
45+
import com.duckduckgo.app.browser.tabs.adapter.TabSwitcherItemDiffCallback.Companion.DIFF_KEY_VIEWED
4446
import com.duckduckgo.app.tabs.model.TabEntity
4547
import com.duckduckgo.app.tabs.model.TabSwitcherData.LayoutType
4648
import com.duckduckgo.app.tabs.ui.TabSwitcherAdapter.TabSwitcherViewHolder.Companion.GRID_TAB
@@ -115,6 +117,19 @@ class TabSwitcherAdapter(
115117
}
116118
}
117119

120+
@VisibleForTesting
121+
fun createCloseClickListener(
122+
bindingAdapterPosition: () -> Int,
123+
tabSwitcherListener: TabSwitcherListener,
124+
): View.OnClickListener {
125+
return View.OnClickListener {
126+
val position = bindingAdapterPosition()
127+
if (position != RecyclerView.NO_POSITION) {
128+
tabSwitcherListener.onTabDeleted(position = position, deletedBySwipe = false)
129+
}
130+
}
131+
}
132+
118133
private fun bindListTab(holder: TabSwitcherViewHolder.ListTabViewHolder, tab: TabEntity) {
119134
val context = holder.binding.root.context
120135
holder.title.text = extractTabTitle(tab, context)
@@ -124,7 +139,7 @@ class TabSwitcherAdapter(
124139
loadFavicon(tab, holder.favicon)
125140
attachTabClickListeners(
126141
tabViewHolder = holder,
127-
bindingAdapterPosition = holder.bindingAdapterPosition,
142+
bindingAdapterPosition = { holder.bindingAdapterPosition },
128143
tab = tab,
129144
)
130145
}
@@ -138,7 +153,7 @@ class TabSwitcherAdapter(
138153
loadTabPreviewImage(tab, glide, holder)
139154
attachTabClickListeners(
140155
tabViewHolder = holder,
141-
bindingAdapterPosition = holder.bindingAdapterPosition,
156+
bindingAdapterPosition = { holder.bindingAdapterPosition },
142157
tab = tab,
143158
)
144159
}
@@ -252,15 +267,18 @@ class TabSwitcherAdapter(
252267
}
253268
}
254269

255-
private fun attachTabClickListeners(tabViewHolder: TabViewHolder, bindingAdapterPosition: Int, tab: TabEntity) {
270+
private fun attachTabClickListeners(tabViewHolder: TabViewHolder, bindingAdapterPosition: () -> Int, tab: TabEntity) {
256271
tabViewHolder.rootView.setOnClickListener {
257272
if (!isDragging) {
258273
itemClickListener.onTabSelected(tab)
259274
}
260275
}
261-
tabViewHolder.close.setOnClickListener {
262-
itemClickListener.onTabDeleted(bindingAdapterPosition, false)
263-
}
276+
tabViewHolder.close.setOnClickListener(
277+
createCloseClickListener(
278+
bindingAdapterPosition = bindingAdapterPosition,
279+
tabSwitcherListener = itemClickListener,
280+
),
281+
)
264282
}
265283

266284
fun updateData(updatedList: List<TabSwitcherItem>) {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.tabs.tabs.ui
18+
19+
import androidx.test.ext.junit.runners.AndroidJUnit4
20+
import com.duckduckgo.app.browser.favicon.FaviconManager
21+
import com.duckduckgo.app.browser.tabpreview.WebViewPreviewPersister
22+
import com.duckduckgo.app.tabs.ui.TabSwitcherAdapter
23+
import com.duckduckgo.app.tabs.ui.TabSwitcherListener
24+
import com.duckduckgo.common.utils.DispatcherProvider
25+
import org.junit.Test
26+
import org.junit.runner.RunWith
27+
import org.mockito.kotlin.mock
28+
import org.mockito.kotlin.verify
29+
30+
@RunWith(AndroidJUnit4::class)
31+
class TabSwitcherAdapterTestAndroid {
32+
33+
private val mockTabSwitchListener: TabSwitcherListener = mock()
34+
private val testee: TabSwitcherAdapter = createMockTabSwitcherAdapter(
35+
listener = mockTabSwitchListener,
36+
)
37+
38+
@Test
39+
fun `close click listener returns current position`() {
40+
var currentPosition = 5
41+
val positionProvider = { currentPosition }
42+
43+
val clickListener = testee.createCloseClickListener(positionProvider, mockTabSwitchListener)
44+
45+
clickListener.onClick(mock())
46+
verify(mockTabSwitchListener).onTabDeleted(5, false)
47+
48+
currentPosition = 3
49+
50+
clickListener.onClick(mock())
51+
verify(mockTabSwitchListener).onTabDeleted(3, false)
52+
}
53+
54+
fun createMockTabSwitcherAdapter(
55+
listener: TabSwitcherListener,
56+
): TabSwitcherAdapter {
57+
return TabSwitcherAdapter(
58+
itemClickListener = listener,
59+
webViewPreviewPersister = mock<WebViewPreviewPersister>(),
60+
lifecycleOwner = mock(),
61+
faviconManager = mock<FaviconManager>(),
62+
dispatchers = mock<DispatcherProvider>(),
63+
)
64+
}
65+
}

app/version/version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION=5.227.0
1+
VERSION=5.227.1

0 commit comments

Comments
 (0)